viewpager tutorial pageview page example control ios objective-c uipageviewcontroller

ios - tutorial - uipageviewcontroller swift 4



Cómo agregar dos controladores de vista en UIPageViewcontroller (4)

Estoy usando UIPageViewController en iPad donde necesito mostrar un firstviewController en la primera página y ContentViewController en la página siguiente en horizontal.

Si configuro NSArray con dos viewControllers la aplicación se bloquea en [self.pagviewController setViewController:] con la siguiente excepción:

El número de controladores de vista proporcionados (2) no coincide con el número requerido (1) para la ubicación de la columna vertebral solicitada (UIPageViewControllerSpineLocationMin)

A continuación se muestra el código:

#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; }


Ah..Finalmente tengo solución para este mismo problema ..., puede ayudarte ...

Cuando configuramos la ubicación de la columna vertebral en UIPageViewControllerSpineLocationMid , la propiedad de doble doubleSided de pageViewController se establece automáticamente en YES. Esto significa que el contenido en el frente de la página no se mostrará parcialmente a través de la parte posterior. Pero cuando esta propiedad se establece en NO, el contenido en el frente de la página se mostrará parcialmente a través de la parte posterior, dando a la página un efecto de tipo translúcido. Por lo tanto, en la orientación vertical, tenemos que establecer el valor en NO, de lo contrario, resultaría en una excepción.

Por lo tanto, en su método de delegado UIPageviewcontroller , en otra parte, agregue esta propiedad de doubleSided como SÍ cuando devuelva spineLocation como UIPageViewControllerSpineLocationMid

self.pageViewController.doubleSided = YES; return UIPageViewControllerSpineLocationMid;


El problema es que pasa una matriz que contiene dos controladores de vista al controlador de vista de página, mientras que espera que uno a la vez, cambie su matriz para que sea así:

NSArray *viewControllers = @[appDelegate.firstViewController];

Pasará una de las vistas, pero viewControllerAfterViewController y viewControllerBeforeViewController se encargarán del resto.


En lugar de implementar un origen de datos completo, puede configurar el PageViewController con un controlador de vista a la vez cada vez que el usuario presione el botón siguiente o atrás, como

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

Esto animará la transición de la página cuando cambies.


self.pageViewController.doubleSided = NO; return UIPageViewControllerSpineLocationMid;

Esta es la solución para la excepción.

En xcode se puede encontrar esto.

Vaya a la clase UIPageViewcontroller y podrá ver la explicación de esto como:

@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''.