2013-12-22 4 views
0

У меня в настоящее время UIPageViewController настроен в моем проекте почти так же, как шаблон приложения по умолчанию по умолчанию.Как я могу сообщить UIPageViewController, когда моя загрузка async завершена?

Однако в методе init для моего ModelController я использую NSURLConnection для async-загрузки данных в массив (изображений), который должен отображаться на PageViewController.

Это означает, что когда мой контроллер корневого представления идет и запускает пульт управления представлением, ресурсы могут еще не загружаться, а затем контроллер модели извлекает вещи из пустого массива, который вызывает сбой приложения.

Как я могу реализовать безопасный способ отображения изображений в PageView? Я думал об использовании пустого контроллера представлений с индикатором активности в качестве стартового контроллера представления, но я не знаю, как я мог бы затем сообщить контроллеру модели, когда загрузка будет завершена, чтобы затем я мог обновлять представления изображениями.

мой контроллер зрения корень (это uipageviewcontroller делегат)

@interface CSAPromoViewController() 
@property (readonly, strong, nonatomic) CSAPromoModelController *modelController; 
@end 

@implementation CSAPromoViewController 

@synthesize modelController = _modelController; 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

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

    CSAPageDataViewController *startingViewController = [self.modelController viewControllerAtIndex:0 storyboard:self.storyboard]; 
    NSArray *viewControllers = @[startingViewController]; 
    [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil]; 

    self.pageViewController.dataSource = self.modelController; 

    [self addChildViewController:self.pageViewController]; 
    [self.view addSubview:self.pageViewController.view]; 

    //set page view controller's bounds 
    CGRect pageViewRect = self.view.bounds; 
    self.pageViewController.view.frame = pageViewRect; 

    [self.pageViewController didMoveToParentViewController:self]; 

    self.view.gestureRecognizers = self.pageViewController.gestureRecognizers; 

} 

моя модель контроллера (это источник данных)

@interface CSAPromoModelController() 
@property (readonly, strong, nonatomic) NSArray *promosArray; 
@end 

@implementation CSAPromoModelController 
-(id)init 
{ 
    self = [super init]; 
    if (self) { 
     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://blah.com"] 
              cachePolicy:NSURLRequestUseProtocolCachePolicy 
             timeoutInterval:60.0]; 
     [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 
      _promosArray = [self parseJSON:data]; 
     }]; 
    } 
    return self; 
} 

- (CSAPageDataViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard 
{ 
    // Return the data view controller for the given index. 
    if (([self.promosArray count] == 0) || (index >= [self.promosArray count]/2)) { 
     return nil; 
    } 

    // Create a new view controller and pass suitable data. 
    CSAPageDataViewController *dataViewController = [storyboard instantiateViewControllerWithIdentifier:@"CSAPageDataViewController"]; 
    dataViewController.promoOne = [self.promosArray objectAtIndex:index * 2]; 
    dataViewController.promoTwo = [self.promosArray objectAtIndex:(index * 2) + 1]; 
    return dataViewController; 
} 

контроллер просмотра данных

@implementation CSAPageDataViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
// Do any additional setup after loading the view. 
    self.promoLabelTop.text = [self.promoOne name]; 
    self.promoImageTop.image = [self.promoOne image]; 
    self.promoLabelBottom.text = [self.promoTwo name]; 
    self.promoImageBottom.image = [self.promoTwo image]; 
} 
+1

Можете ли вы показать код на странице контроллера? – Unheilig

+1

Да, конечно, одна секунда –

ответ

1

Ваша проблема, которую вы пытаетесь решить, - это асинхронный. Однако ваш подход предназначен для решения проблемы синхронного.

Например, ваш класс CSAPromoModelController по своей сути является асинхронным. Это связано с тем, что метод init вызывает асинхронный метод, и поэтому ваш класс получает «заражение» асинхронизмом.

Вы можете подумать о перепроектировании, где класс CSAPromoModelController становится подклассом NSOperation с полным обработчиком, например. CSAPromoModelOperation. Это в конечном итоге результатом является массив изображений. imageArray становится ivar вашего CSAPromoViewController. CSAPromoViewController будет иметь способ создания объекта CSAPromoModelController, который будет инициализирован изображением. Обработчик завершения операции передает массив изображений. Внутри обработчика завершения вы в основном выполняете те же инструкции, что и в вашем исходном методе viewDidLoad, чтобы настроить контроллеры.

Вы бы использовать операцию следующим образом:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

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

    NSURLRequest *request = ... 
    CSAPromoModelOperation* op = 
     [CSAPromoModelOperation alloc] initWithRequest:request 
            completion:^(NSArray* result, NSError*error) 
    { 
     // assuming we are executing on the main thread! 
     if (error == nil) { 
      self.imageArray = result; 
      CSAPageDataViewController* startingViewController = 
       [self viewControllerWithImage:self.imageArray[0] 
            storyboard:self.storyboard]; 
      NSArray* viewControllers = @[startingViewController]; 
      [self.pageViewController setViewControllers:viewControllers 
               direction:UIPageViewControllerNavigationDirectionForward 
               animated:NO 
              completion:nil]; 
      ... 
     } 
     else { 
      // handle error 
     } 
    }]; 

    [op start]; 
} 
Смежные вопросы