Loading data on a UIViewController: viewDidLoad and viewWillAppear - What is the proper logic?
I have a tabBarControllerView with a UIScrollViewController in its third tab. I'm loading essentially the same thing, pictures from core data, in viewDidLoad and viewWillAppear. I'm thinking that viewWillAppear is what I can use to update the view in UIScrollView. The only thing is when I add pictures to core data the correct picture isn't being displayed.
I'm wondering if it's my viewWillAppear logic or if my context is off? I'm working on fixing my context so if my logic is sound (minus the ManagedObjectContext) then that will be great to hear - as I can go back to working on the context issue.
If it's the logic then I'd really appreciate if you could point out my flaw(s) :-)
Header file
#import <UIKit/UIKit.h>
#import "PhotoViewController.h"
@interface MyTabBarViewController : UIViewController<UIScrollViewDelegate>
{
IBOutlet UIPageControl *pageControl;
IBOutlet UIScrollView *scroller;
UIImage *image;
CGFloat scrollWidth;
int pageNumber;
}
@property (nonatomic,retain)IBOutlet UIPageControl *pageControl;
@property (nonatomic,retain)IBOutlet UIScrollView *scroller;
-(IBAction)clickPageControl:(id)sender;
@end
Implementation file ... relevant snippets
- (void)viewDidLoad
{
[super viewDidLoad];
scroller.delegate=self;
scroller.pagingEnabled=YES;
scroller.directionalLockEnabled=YES;
scroller.showsHorizontalScrollIndicator=NO;
scroller.showsVerticalScrollIndicator=NO;
scroller.contentSize=CGSizeMake(pageControl.numberOfPages*scroller.frame.size.width, scroller.frame.size.height);
scrollWidth = 0;
pageNumber = 0;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [(CoreDataProjAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
request.entity = [NSEntityDescription entityForName:@"Photo" inManagedObjectContext:context];
NSError *error = nil;
NSArray *fetchCount = [context executeFetchRequest:request error:&error];
int pageCount = [fetchCount count];
for (int i=pageNumber; i<pageCount; i++)
{
PhotoViewController *pvc = [[PhotoViewController alloc] initWithNibName:@"PhotoViewController" bundle:nil];
CGRect rect = scroller.frame;
rect.size.height = scroller.frame.size.height;
开发者_如何转开发 rect.size.width = scroller.frame.size.width;
rect.origin.x = scroller.frame.origin.x + scrollWidth;
rect.origin.y = scroller.frame.origin.y;
pvc.view.frame = rect;
[pvc view];
pvc.label.text = [NSString stringWithFormat:@"%d", pageNumber];
pvc.label.textColor = [UIColor redColor];
Photo *photo = [[Photo alloc] init];
photo = [fetchCount objectAtIndex:i];
UIImage *fetchedImage = [UIImage imageWithData:photo.photo];
pvc.imageView.image = fetchedImage;
[scroller addSubview:pvc.view];
[pvc release];
pageNumber++;
scrollWidth += scroller.frame.size.width;
}
pageControl.numberOfPages=pageCount;
pageControl.currentPage=0;
[self.view addSubview:scroller];
[request release];
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:YES];
scroller.delegate=self;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [(CoreDataProjAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
request.entity = [NSEntityDescription entityForName:@"Photo" inManagedObjectContext:context];
NSError *error = nil;
NSArray *fetchCount = [context executeFetchRequest:request error:&error];
int pageCount = [fetchCount count];
scroller.contentSize=CGSizeMake(pageCount*scroller.frame.size.width, scroller.frame.size.height);
for (int i=pageNumber; i<pageCount; i++)
{
PhotoViewController *pvc = [[PhotoViewController alloc] initWithNibName:@"PhotoViewController" bundle:nil];
CGRect rect = scroller.frame;
rect.size.height = scroller.frame.size.height;
rect.size.width = scroller.frame.size.width;
rect.origin.x = scroller.frame.origin.x + scrollWidth;
rect.origin.y = scroller.frame.origin.y;
pvc.view.frame = rect;
[pvc view];
pvc.label.text = [NSString stringWithFormat:@"%d", pageNumber];
pvc.label.textColor = [UIColor redColor];
Photo *photo = [[Photo alloc] init];
photo = [fetchCount objectAtIndex:i];
UIImage *fetchedImage = [UIImage imageWithData:photo.photo];
pvc.imageView.image = fetchedImage;
[scroller addSubview:pvc.view];
[pvc release];
pageNumber++;
scrollWidth += scroller.frame.size.width;
}
pageControl.numberOfPages=pageCount;
pageControl.currentPage=0;
[self.view addSubview:scroller];
[request release];
}
I don't know if this is the actual cause, but one thing I notice is that in your for loop, you are manually incrementing pageNumber++
and I'm not entirely sure why. If you take any internal reference of pageNumber
in the loop (I only see the line where you're setting the label text offhand) and replace that with i
, I believe this should let you display your images properly. In short, just take pageNumber
out of the code (unless there's something I'm clearly overlooking) and just use for (int i = 0; i < pageCount; i++) {
. If nothing more, this will give you more control over your loop and eliminate any varying changes during each loop increment. As for which method to use, it's most likely best to implement the code in viewWillAppear
since it will give the view more of a chance to load and give you proper dimensions when you display your images.
EDIT: If you're looking to display the images in a certain order, you won't be able to do that directly by fetching the objects from the managedObjectContext since it stores its objects as an NSSet (unindexed). If you want to display the pictures in a particular order, you will need to use a sort descriptor. So when you're creating your request, you'll want to follow something like this:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [(CoreDataProjAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
request.entity = [NSEntityDescription entityForName:@"Photo" inManagedObjectContext:context];
NSError *error = nil;
NSSortDescriptor *sorter = [NSSortDescriptor sortDescriptorWithKey:@"someAttributeToIndex" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sorter]];
NSArray *fetchCount = [context executeFetchRequest:request error:&error];
Doing this should let you actually specify the order which you want to present the images, either by date added or an integer index (which you will have to add as an attribute to the entity)
精彩评论