Pregunta

I'm using a UIPageViewController to display items from a JSON file. It works fine except for the first page which displays nothing on loading, but if I come back, it works.

Code is as follows:

#import "SJPagesViewController.h"
#import "SJChildViewController.h"

@interface SJPagesViewController ()

@end

@implementation SJPagesViewController
@synthesize urlToFollow, data,articlesArray;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
   ...
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

    CGFloat window_height = ([self window_height]-30.0);
    CGFloat window_width  = [self window_width];
    CGRect pageFrame = CGRectMake(0.0f, 0.0f,window_width , window_height);

    self.pageController.dataSource = self;
    [[self.pageController view] setFrame:pageFrame];

    SJChildViewController *initialViewController = [self viewControllerAtIndex:0];

    NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];

    [self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

    [self addChildViewController:self.pageController];
    [[self view] addSubview:[self.pageController view]];
    [self.pageController didMoveToParentViewController:self];


    //Download JSON
    NSError *error=nil;

    NSURL *url = [NSURL URLWithString:urlToFollow];

    data = [NSData dataWithContentsOfURL: url options:NSDataReadingMappedIfSafe error:&error];
    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

    NSArray *response = [dictionary objectForKey:@"items"];

    articlesArray = [[NSArray alloc] initWithArray:response];
    //NSLog(@"articlesArray = %@", articlesArray);


}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController {

    NSUInteger index = [(SJChildViewController *)viewController index];

    if (index == 0) {
        return nil;
    }
    index--;

    return [self viewControllerAtIndex:index];
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController {

    NSUInteger index = [(SJChildViewController *)viewController index];
    index++;

    if (index == articlesArray.count) {
        return nil;
    }

    return [self viewControllerAtIndex:index];

}

- (CGFloat) window_height   {
    return [UIScreen mainScreen].applicationFrame.size.height;
}

- (CGFloat) window_width   {
    return [UIScreen mainScreen].applicationFrame.size.width;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (SJChildViewController *)viewControllerAtIndex:(NSUInteger)index {

    SJChildViewController *childViewController = [[SJChildViewController alloc] initWithNibName:@"SJChildViewController" bundle:nil];
    childViewController.index = index;
    childViewController.arrayCount = self.articlesArray.count;
    childViewController.model = [[self.articlesArray objectAtIndex:index]objectForKey:@"modelo"];
    childViewController.price = [[self.articlesArray objectAtIndex:index]objectForKey:@"precio"];
    childViewController.make = [[self.articlesArray objectAtIndex:index]objectForKey:@"marca"];
    childViewController.imageUrl = [[self.articlesArray objectAtIndex:index]objectForKey:@"photoUrl"];

    return childViewController;

}

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController {
    // The number of items reflected in the page indicator.
    if (articlesArray.count >5) {
        return 5;
    }else return [articlesArray count];
}

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController {
    // The selected item reflected in the page indicator.
    return 0;
}

@end

And ChildViewController to display items:

@implementation SJChildViewController
@synthesize activityIndicator,imageUrl,price,model,make;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    ....
}

- (void)viewDidLoad

{
    [super viewDidLoad];

    //Activity indicator
    activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    activityIndicator.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
    [self.view addSubview: activityIndicator];

    [activityIndicator startAnimating];

}
-(void)viewDidAppear:(BOOL)animated{
    self.scrrenNumber.text = [NSString stringWithFormat:@"Artículo %ld de %ld", ((long)self.index+1), (long)self.arrayCount];

    self.lblMake.lineBreakMode = NSLineBreakByWordWrapping;
    self.lblMake.text = [NSString stringWithFormat:@"%@",make];

    //Donload image
    //Download image from url
    NSURL *url_1= [NSURL URLWithString:imageUrl];
    NSURLRequest *request_1 = [NSURLRequest   requestWithURL:url_1];
    [NSURLConnection sendAsynchronousRequest:request_1
                                       queue:[NSOperationQueue currentQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
                               UIImage  *img = [UIImage imageWithData:data];
                               [self.articleImage performSelectorOnMainThread:@selector(setImage:) withObject:img waitUntilDone:YES];
                           }];
    //Activity indicator

    self.lblPrice.text = [NSString stringWithFormat:@"%@",price];
    self.lblModel.lineBreakMode = NSLineBreakByWordWrapping;
    self.lblModel.text = [NSString stringWithFormat:@"%@",model];
    [activityIndicator stopAnimating];
}

How can I make it work from the first moment?

¿Fue útil?

Solución

Luis, I don't have access to xcode right now but it appears your issue is that you are instantiating childViewController while articlesArray is empty.

In viewDidLoad you are downloading your json file and populating articlesArray after you call your helper method viewControllerAtIndex.

Try downloading your json file and populating the array first like you have here.

//Download JSON
NSError *error=nil;

NSURL *url = [NSURL URLWithString:urlToFollow];

data = [NSData dataWithContentsOfURL: url options:NSDataReadingMappedIfSafe error:&error];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

NSArray *response = [dictionary objectForKey:@"items"];

articlesArray = [[NSArray alloc] initWithArray:response];

Then create your pageViewController and populate it like you did here.

self.pageController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];

CGFloat window_height = ([self window_height]-30.0);
CGFloat window_width  = [self window_width];
CGRect pageFrame = CGRectMake(0.0f, 0.0f,window_width , window_height);

self.pageController.dataSource = self;
[[self.pageController view] setFrame:pageFrame];

SJChildViewController *initialViewController = [self viewControllerAtIndex:0];

NSArray *viewControllers = [NSArray arrayWithObject:initialViewController];

[self.pageController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];

[self addChildViewController:self.pageController];
[[self view] addSubview:[self.pageController view]];
[self.pageController didMoveToParentViewController:self];
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top