2013-12-22 103 views
0

我目前在我的項目中設置了一個UIPageViewController,幾乎完全像默認的基於頁面的應用程序模板。如何讓UIPageViewController知道我的異步下載是否完成?

但是,在我的ModelController的init方法中,我使用NSURLConnection將異步數據下載到應該顯示在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成爲您的CSAPromoViewController的一個ivar。 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]; 
} 
相關問題