2013-04-04 1 views
27

Sto usando UIPageViewController su iPad dove ho bisogno di mostrare un firstviewController nella prima pagina e ContentViewController nella pagina successiva in orizzontale.come aggiungere due controller di vista in UIPageViewcontroller

Se regolo il NSArray con due viewControllers l'applicazione è crash al [self.pagviewController setViewController:] con le seguenti eccezioni:

Il numero di controllori visualizzazione fornita (2) non corrisponde al numero richiesto (1) per la richiesto posizione della colonna vertebrale (UIPageViewControllerSpineLocationMin)

Di seguito è riportato il codice:

#pragma mark - UIPageViewControllerDataSource Methods 

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController 
     viewControllerBeforeViewController:(UIViewController *)viewController 
{ 
    NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentViewController *)viewController textContents]]; 
    if(currentIndex == 0) 
    { 
     return nil; 
    } 
    ContentViewController *contentViewController = [[ContentViewController alloc] init]; 
    contentViewController.textContents = [self.modelArray objectAtIndex:currentIndex - 1]; 
    return contentViewController; 
} 

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController 
     viewControllerAfterViewController:(UIViewController *)viewController 
{ 
    NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentViewController *)viewController textContents]]; 
    if(currentIndex == self.modelArray.count-1) 
    { 
     return nil; 
    } 
    ContentViewController *contentViewController = [[ContentViewController alloc] init]; 
    contentViewController.textContents = [self.modelArray objectAtIndex:currentIndex + 1]; 

    return contentViewController; 
} 




//#pragma mark - UIPageViewControllerDelegate Methods 

- (UIPageViewControllerSpineLocation)pageViewController:(UIPageViewController *)pageViewController 
        spineLocationForInterfaceOrientation:(UIInterfaceOrientation)orientation 
{ 
    if(UIInterfaceOrientationIsPortrait(orientation)) 
    { 
     //Set the array with only 1 view controller 
     UIViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0]; 
     NSArray *viewControllers = [NSArray arrayWithObject:currentViewController]; 

     [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL]; 

     //Important- Set the doubleSided property to NO. 
     self.pageViewController.doubleSided = NO; 
     //Return the spine location 
     return UIPageViewControllerSpineLocationMin; 
    } 
    else 
    { 
     NSArray *viewControllers = nil; 
     ContentViewController *currentViewController = [self.pageViewController.viewControllers objectAtIndex:0]; 

     NSUInteger currentIndex = [self.modelArray indexOfObject:[(ContentViewController *)currentViewController textContents]]; 
     if(currentIndex == 0 || currentIndex %2 == 0) 
     { 
      UIViewController *nextViewController = [self pageViewController:self.pageViewController viewControllerAfterViewController:currentViewController]; 
      viewControllers = [NSArray arrayWithObjects:currentViewController, nextViewController, nil]; 
     } 
     else 
     { 
      UIViewController *previousViewController = [self pageViewController:self.pageViewController viewControllerBeforeViewController:currentViewController]; 
      viewControllers = [NSArray arrayWithObjects:previousViewController, currentViewController, nil]; 
     } 
     //Now, set the viewControllers property of UIPageViewController 
     [self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:YES completion:NULL]; 

     return UIPageViewControllerSpineLocationMid; 
    } 
} 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    appDelegate = (AppDelegate *) [[UIApplication sharedApplication] delegate]; 
    //Instantiate the model array 
    self.modelArray = [[NSMutableArray alloc] init]; 
    self.vcs = [[NSMutableArray alloc]init]; 

    for (int index = 1; index <= 2 ; index++) 
    { 
     [self.modelArray addObject:[NSString stringWithFormat:@"Page %d",index]]; 
    } 

    //Step 1 
    //Instantiate the UIPageViewController. 
    self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl 
                   navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil]; 
    //Step 2: 
    //Assign the delegate and datasource as self. 
    self.pageViewController.delegate = self; 
    self.pageViewController.dataSource = self; 

    //Step 3: 
    //Set the initial view controllers. 

    appDelegate.contentViewController.textContents = [self.modelArray objectAtIndex:0]; 


    NSArray *viewControllers = [NSArray arrayWithObjects:appDelegate.firstViewController,appDelegate.contentViewController,nil]; 
    [self.pageViewController setViewControllers:viewControllers 
             direction:UIPageViewControllerNavigationDirectionForward 
             animated:NO 
            completion:nil]; 

    //Step 4: 
    //ViewController containment steps 
    //Add the pageViewController as the childViewController 
    [self addChildViewController:self.pageViewController]; 

    //Add the view of the pageViewController to the current view 
    [self.view addSubview:self.pageViewController.view]; 

    //Call didMoveToParentViewController: of the childViewController, the UIPageViewController instance in our case. 
    [self.pageViewController didMoveToParentViewController:self]; 

    //Step 5: 
    // set the pageViewController's frame as an inset rect. 
    CGRect pageViewRect = self.view.bounds; 
    pageViewRect = CGRectInset(pageViewRect, 40.0, 40.0); 
    self.pageViewController.view.frame = pageViewRect; 

    //Step 6: 
    //Assign the gestureRecognizers property of our pageViewController to our view's gestureRecognizers property. 
    self.view.gestureRecognizers = self.pageViewController.gestureRecognizers; 
} 
+1

È necessario fornire una pagina alla volta tramite il dataSource se solo si desidera visualizzare una pagina, è per questo che la vostra applicazione si blocca - ha due pagine da mostrare quando se ne prevede una (quando in modalità verticale credo). Mostraci il tuo delegato e il codice sorgente dati. –

+1

amico sicuro ....... ma l'applicazione creash in viewDidLoad – user578386

+0

controlla il codice sopra – user578386

risposta

-2

Invece di implementare una sorgente di dati completo, è possibile impostare la PageViewController con un controller vista alla volta ogni volta che l'utente preme un pulsante accanto o indietro, come

[pageViewController setViewControllers:@[contentViewController] 
          direction:UIPageViewControllerNavigationDirectionForward 
           animated:YES 
          completion:nil]; 

Questo animerà la transizione pagina come si passa.

1

Ah..Finally got soluzione per lo stesso problema .., può aiuta te ..

Quando abbiamo la posizione della colonna vertebrale al UIPageViewControllerSpineLocationMid, di proprietà del pageViewController doubleSided viene automaticamente impostata su YES. Ciò significa che il contenuto della pagina frontale non verrà visualizzato parzialmente indietro. Ma quando questa proprietà è impostata su NO, il contenuto sul fronte della pagina verrà mostrato parzialmente indietro, dando alla pagina un tipo di effetto traslucido. Quindi, nell'orientamento verticale, dobbiamo impostare il valore su NO, altrimenti risulterebbe un'eccezione.

Quindi nel tuo metodo delegato UIPageviewcontroller, in parte altro Aggiungi questa proprietà doubleSided come YES quando si torna spineLocation come UIPageViewControllerSpineLocationMid

self.pageViewController.doubleSided = YES; 
return UIPageViewControllerSpineLocationMid; 
19

Il problema è che si passa una matrice contenente due vista controller per la visualizzazione della pagina di controllo, mentre si aspetta una alla volta, cambiare la matrice per essere come questo:

NSArray *viewControllers = @[appDelegate.firstViewController]; 

passerete una delle viste, ma viewControllerAfterViewController e viewControllerBeforeViewController gestirà il resto.

+6

Perché il parametro per questa chiamata è un array se si aspetta solo un controller di visualizzazione? – Shoerob

+6

@Shoerob Secondo la documentazione 'Per lo stile di transizione 'UIPageViewControllerTransitionStylePageCurl', se 'doubleSided' è 'YES' e la posizione del dorso non è 'UIPageViewControllerSpineLocationMid', devono essere inclusi due controller di vista, in quanto quest'ultimo viene utilizzato come retro controller .' –

0
self.pageViewController.doubleSided = NO; 
return UIPageViewControllerSpineLocationMid; 

Questa è la soluzione per l'eccezione.

In xcode è possibile trovare questo.

Vai alla classe UIPageViewcontroller ci si poteva vedere la spiegazione di questo tipo:

@property (nonatomic, readonly) UIPageViewControllerSpineLocation spineLocation; // If transition style is 'UIPageViewControllerTransitionStylePageCurl', default is 'UIPageViewControllerSpineLocationMin', otherwise 'UIPageViewControllerSpineLocationNone'. 

// Whether client content appears on both sides of each page. If 'NO', content on page front will partially show through back. 
// If 'UIPageViewControllerSpineLocationMid' is set, 'doubleSided' is set to 'YES'. Setting 'NO' when spine location is mid results in an exception. 
@property (nonatomic, getter=isDoubleSided) BOOL doubleSided; // Default is 'NO'.