UIPageViewController: devuelve la vista visible actual

89

¿Cómo sabe cuál es la página / vista actual que se muestra dentro de un UIPageViewController?

He anulado el viewDidAppearmétodo de las vistas de mis hijos, para que envíen una identificación a la vista principal en su viewDidAppearmétodo.

Sin embargo, el problema es este: no puedo usar esa identificación de manera confiable como identificación para la página mostrada. porque si el usuario pasa la página pero a la mitad decide detener el paso y volver a colocar la página, viewDidAppearya habrá sido llamado. (la vista es visible detrás de la página enrollada).

Tal vez solo debería cambiar a una nueva identificación si la vista actual desaparece. Pero me pregunto si no hay una forma más sencilla de devolver la vista que es actualmente visible.

ene
fuente
¿Ha intentado usar en su viewDidAppear:animated:lugar?
Hasta el
Oh si. Usé eso. Edité la pregunta para corregir mi error.
enero
La forma en que editó la pregunta no tiene sentido para mí. O envía esa identificación desde viewWillAppear o desde viewDidAppear. Vuelva a comprobar su edición.
Hasta el
Lo siento, hice un mal trabajo editando la pregunta. Usé viewDidAppear todo el tiempo. Espero que mi última edición aclare eso.
enero
Echen un vistazo aquí chicos, esto funciona para mí stackoverflow.com/a/36860663/4286947
theDC

Respuestas:

103

Debe realizar un seguimiento manual de la página actual. El método delegado pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:le dirá cuándo actualizar esa variable. El último argumento del método transitionCompleted:puede indicarle si un usuario completó una transición de cambio de página o no.

Ole Begemann
fuente
1
+1 para la respuesta correcta: desearía tener la oportunidad de trabajar con UIPageViewController y ser compatible solo con iOS5.
Hasta el
Gracias, esa es exactamente la solución limpia que estaba buscando. mejor que los delegados en las páginas.
enero
3
Cuando gira el dispositivo, ¿cómo realiza un seguimiento de la página actual?
Satyam
@hasta que pueda, simplemente configure la versión mínima de su proyecto en ios5.0
mtmurdock
83
¿Cómo puede saber si debe aumentar o disminuir el número de página actual?
calce el
59

A partir de iOS 6, descubrí que la viewControllerspropiedad de UIPageViewController se actualiza constantemente para que siempre contenga el controlador de una vista que representa la página actual, y nada más. Por lo tanto, puede acceder a la página actual llamando viewControllers[0](suponiendo que solo muestre un controlador de vista a la vez).

La matriz viewController solo se actualiza una vez que la página "se bloquea" en su lugar, por lo que si un usuario decide revelar parcialmente la página siguiente, no se convierte en la página "actual" a menos que complete la transición.

Si desea realizar un seguimiento de los "números de página", asigne a sus controladores de vista un valor de índice a medida que los crea a través de los métodos de origen de datos UIPageViewController.


Así por ejemplo:

-(void)autoAdvance
    {
    UIViewController *currentVC = self.viewControllers[0];
    NSUInteger currentIndex = [myViewControllers indexOfObject:currentVC];

    if ( currentIndex >= (myViewControllers.count-1) ) return;

    [self setViewControllers:@[myViewControllers[ currentIndex+1 ]]
        direction:UIPageViewControllerNavigationDirectionForward
        animated:YES
        completion:nil];
    }
-(NSInteger)presentationIndexForPageViewController:
                         (UIPageViewController *)pageViewController
    {
    // return 0;
    UIViewController *currentVC = self.viewControllers[0];
    NSUInteger currentIndex = [myViewControllers indexOfObject:currentVC];
    return currentIndex;
    }

Pero tenga en cuenta los comentarios de que esto no es confiable.

Eddy Borja
fuente
2
Lo encontré poco confiable. No pude encontrar la fuente del problema. Cuando finaliza la animación, accedo a la viewControllerspropiedad y obtengo los controladores de vista correctos, pero cuando giro, en el método spineLocationForInterfaceOrientation, ya no obtengo los controladores de vista correctos. Así que me limité a mantener mi propia propiedad currentPage en lugar de depender siempre de viewControllers.
Fábio Oliveira
Interesante, jugaré un poco con él para ver cómo se comporta en estos casos especiales
Eddy Borja
2
También me pareció poco fiable. Parece que Apple solo llama a viewControllerBeforeViewController o viewControllerAfterViewController para cada vuelta de página, pero no actualiza UIPageViewController.viewControllers. No sé cómo se las arreglan para hacer mal este tipo de cosas, pero lo hacen. Realmente aumenta mi carga de trabajo y rompe la claridad de mi código (a menudo violando DRY y otros principios).
Zack Morris
3
@ZackMorris. Es absolutamente increíble, tienes toda la razón. Es un "momento de terror de Apple". ¿Por qué no incluirían las funciones obvias como mover uno a la derecha, en qué página estoy actualmente, etc. Es bastante increíble que no puedas "obtener la página en la que estás"?
Fattie
1
self.viewControllers [0] parece funcionar bien para mí. Pero solo llamo a setViewControllers una vez durante el inicio y dejé el resto a la automatización. (probado en iOS 8.4)
Bob
45

Desafortunadamente, todos los métodos anteriores no me ayudaron. Sin embargo, he encontrado la solución usando etiquetas. Puede que no sea lo mejor, pero funciona y espero que ayude a alguien:

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed 
{
    if (completed) {
        int currentIndex = ((UIViewController *)self.pageViewController.viewControllers.firstObject).view.tag;
        self.pageControl.currentPage = currentIndex;
    }
}

En Swift: (gracias a @Jessy )

func pageViewController(pageViewController: UIPageViewController,
    didFinishAnimating finished: Bool,
    previousViewControllers: [UIViewController],
    transitionCompleted completed: Bool)
{
    guard completed else { return }
    self.pageControl.currentPage = pageViewController.viewControllers!.first!.view.tag
}

Ejemplo: gist

Víctor
fuente
3
Esto parece el más sencillo y funcionó bien para mí. Configuré las etiquetas al agregar los controladores de vista (por ejemplo, HelpPage1ViewController * page1 = [self.storyboard instantiateViewControllerWithIdentifier: @ "page1"]; page1.view.tag = 0;). Luego, puede establecer una propiedad currentPage para que el controlador de vista maestro realice un seguimiento de dónde se encuentra. Asegúrese de agregar ambos protocolos ("<UIPageViewControllerDataSource, UIPageViewControllerDelegate>"), no solo la fuente de datos, y configure el delegado como self ("self.pageViewController.delegate = self;") o no se llamará al método. Esto me desconcertó un poco.
James Toomey
1
@VictorM esta solución no me funciona. Tengo un pageViewController con diferentes imágenes. Sigue devolviendo la etiqueta 0 por cada deslizamiento, ¿alguna idea de por qué sucede esto? Gracias de antemano
theDC
1
@VictorM Pasé varios días tratando de guardar el índice, pero accidentalmente encontré esta respuesta, me gustaría poder votar 1000 veces, ¡gracias!
Evgeniy Kleban
1
Gran solución Gracias pasamos horas tratando de evitar esto
Vision Mkhabela
Solo devuelve un valor de 0. ¿Estoy haciendo algo mal?
N. Der
35

Basándose en la respuesta de Ole ...

Así es como implementé los 4 métodos para rastrear la página actual y actualizar el indicador de página al índice correcto:

- (NSInteger)presentationCountForPageViewController:(UIPageViewController *)pageViewController{

    return (NSInteger)[self.model count];

}

- (NSInteger)presentationIndexForPageViewController:(UIPageViewController *)pageViewController{

    return (NSInteger)self.currentIndex;
}

- (void)pageViewController:(UIPageViewController *)pageViewController willTransitionToViewControllers:(NSArray *)pendingViewControllers{

    SJJeanViewController* controller = [pendingViewControllers firstObject];
    self.nextIndex = [self indexOfViewController:controller];

}

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{

    if(completed){

        self.currentIndex = self.nextIndex;

    }

    self.nextIndex = 0;

}
Corey Floyd
fuente
2
Creo que la última línea debería ser en self.nextIndex = self.currentIndexlugar de self.nextIndex = 0para restaurar correctamente el índice cuando no se completa una transición. De lo contrario, corre el riesgo de terminar con un currentIndexvalor de 0 al desplazarse rápidamente hacia adelante y hacia atrás en algún lugar en el medio de sus páginas.
hverlind
1
Esto no me funciona del todo. A veces, pageViewController: willTransitionToViewControllers no se llama y, por lo tanto, nextIndex no se cambia, y el índice actual es incorrecto.
Hayden Holligan
31

La siguiente solución funcionó para mí.

Apple podría evitar muchas molestias haciendo que la paginación nativa de la vista de desplazamiento UIPageViewController sea más configurable. Tuve que recurrir a superponer un nuevo UIView y UIPageControl solo porque la paginación nativa de UIPageViewController no admite un fondo transparente o un reposicionamiento dentro del marco de la vista.

- (void)pageViewController:(UIPageViewController *)pvc didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed
{
  if (!completed)
  {
    return;
  }
  NSUInteger currentIndex = [[self.pageViewController.viewControllers lastObject] index];
  self.pageControl.currentPage = currentIndex;
}
sirvine
fuente
1
en esto, ¿qué quieres decir con índice?
Yohan
Obtengo el índice (es decir, el número entero que representa la posición del controlador de vista actual en la matriz de self.pageViewController.viewControllers) y luego lo uso para establecer el atributo currentPage de self.pageControl (que espera un valor entero) . ¿Tener sentido?
sirvine
6
el índice es una propiedad personalizada aquí, creo
Adam Johns
El problema con esto es que si desea cambiar la página sin el método de animación, no se llamará
Silviu St
19

Rápido 4

Sin código innecesario. 3 formas de hacerlo. Usando el método UIPageViewControllerDelegate .

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    guard completed else { return }

    // using content viewcontroller's index
    guard let index = (pageViewController.viewControllers?.first as? ContentViewController)?.index else { return }

    // using viewcontroller's view tag
    guard let index = pageViewController.viewControllers?.first?.view.tag else { return }

    // switch on viewcontroller
    guard let vc = pageViewController.viewControllers?.first else { return }
    let index: Int
    switch vc {
    case is FirstViewController:
        index = 0
    case is SecondViewController:
        index = 1
    default:
        index = 2
    }
}
Nikola Milicevic
fuente
¡Gracias a Dios! Yo no sabía pageViewController.viewControllers. ¿Cómo sabes viewControllers? .Primero es el en cuestión?
Script Kitty
En realidad, es bastante simple, la matriz viewControllers contiene solo el controlador de vista presentado actualmente.
Nikola Milicevic
2
¿Cómo accedo a la variable de índice desde esa función?
N. Der
11

Estoy realizando un seguimiento del índice de la página utilizando una pequeña función y especificando pageIndex como NSInteger estático.

-(void) setPageIndex
{
    DataViewController *theCurrentViewController = [self.pageViewController.viewControllers objectAtIndex:0];

    pageIndex = [self.modelController indexOfViewController:theCurrentViewController];
}

y llamando [self setPageIndex];dentro de la función especificada por Ole y también después de detectar el cambio de orientación.

Wahib Ul Haq
fuente
5

Primero usé la solución de Corey pero no funcionaba en iOS5 y luego terminé usando,

- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed{

    if(completed) {
        _currentViewController = [pageViewController.viewControllers lastObject];
    }
}

Intentó cambiar de página y funciona bien por ahora.

Basit Ali
fuente
3

Desafortunadamente, nada de lo anterior funciona para mí.

Tengo dos controladores de vista y cuando desplazo ligeramente (alrededor de 20px) la última vista hacia atrás, se activa el delegado:

pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:

y diciendo que la página actual (índice) es la 0que está mal.

Usando delegado dentro de child viewController algo como:

- (void)ViewController:(id)VC didShowWithIndex:(long)page;

// and a property

@property (nonatomic) NSInteger index;

que se activa en el interior viewDidAppearcomo:

- (void)viewDidAppear:(BOOL)animated
{
    ...

    [self.delegate ViewController:self didShowWithIndex:self.index];
}

Trabajó para mi.

0yeoj
fuente
3

Esto me funciona de manera confiable

Tengo un UIPageController personalizado. Esta pageController.currentPage se actualiza desde el UIViewController mostrado en la vista

   var delegate: PageViewControllerUpdateCurrentPageNumberDelegate?

      init(delegate: PageViewControllerUpdateCurrentPageNumberDelegate ){
        self.delegate = delegate
        super.init(nibName: nil, bundle: nil)
      }

      required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
      }

    override func viewWillAppear(animated: Bool) {

        if delegate != nil {
          self.delegate!.upateCurrentPageNumber(0) //(0) is the pageNumber corresponding to the displayed controller
        }
      } 

    //In the pageViewController 

    protocol PageViewControllerUpdateCurrentPageNumberDelegate {

      func upateCurrentPageNumber(currentPageIndex: Int)
    }

     create the view display controllers initializing with the delegate

    orderedViewControllers = {
              return [
                IntroductionFirstPageViewController(delegate: self),
                IntroductionSecondPageViewController(delegate: self),
                IntroductionThirdPageViewController(delegate: self)
              ]

            }()

    the function implementing the protocol

    func upateCurrentPageNumber(currentPageIndex: Int){
        pageControl.currentPage = currentPageIndex
      }
lguerra10
fuente
1

Lo he estado usando view.tagdurante un tiempo, intentar hacer un seguimiento de la página actual era demasiado complicado.

En este código, el índice se almacena dentro de la tagpropiedad de cada uno viewy se usa para buscar el VC siguiente o anterior. Con este método también es posible crear un desplazamiento infinito. Consulte el comentario en el código para ver también esta solución:

extension MyPageViewController: UIPageViewControllerDataSource {

  func viewControllerWithIndex(var index: Int) -> UIViewController! {
    let myViewController = storyboard?.instantiateViewControllerWithIdentifier("MyViewController") as MyViewController

    if let endIndex = records?.endIndex {
      if index < 0 || index >= endIndex { return nil }
      // Instead, We can normalize the index to be cyclical to create infinite scrolling
      // if index < 0 { index += endIndex }
      // index %= endIndex
    }

    myViewController.view.tag = index
    myViewController.record = records?[index]

    return myViewController
  }

  func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
    let index = viewController.view?.tag ?? 0
    return viewControllerWithIndex(index + 1)
  }

  func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
    let index = viewController.view?.tag ?? 0
    return viewControllerWithIndex(index - 1)
  }

  func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
    return records?.count ?? 0
  }

  func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
    return (pageViewController.viewControllers.first as? UIViewController)?.view.tag ?? 0
  }
}
Yariv Nissim
fuente
1

Gracias por su respuesta chicos, enfrenté un problema similar, tuve que almacenar index. Modifico ligeramente mi código, lo pego a continuación:

- (MenuListViewController *)viewControllerAtIndex:(NSInteger)index {

    if (_menues.count < 1)
        return nil;

    //    MenuListViewController *childViewController = [MenuListViewController initWithSecondSetFakeItems];
    MenuListViewController *childViewController = self.menues[index];
    childViewController.index = index;

    return childViewController;
}

#pragma mark - Page View Controller Data Source

- (void)pageViewController:(UIPageViewController *)pageViewController
        didFinishAnimating:(BOOL)finished
   previousViewControllers:(NSArray<UIViewController *> *)previousViewControllers
       transitionCompleted:(BOOL)completed{

    if (completed) {

        NSUInteger currentIndex = ((MenuListViewController *)self.pageController.viewControllers.firstObject).index;
        NSLog(@"index %lu", (unsigned long)currentIndex);
    }
}

- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
    NSUInteger index = [(MenuListViewController *)viewController index];

    if (index == 0)
        return nil;

    index --;

    return [self viewControllerAtIndex:index];
}


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

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

    index ++;

    if (index == _menues.count)
        return nil;

    return [self viewControllerAtIndex:index];
}
Evgeniy Kleban
fuente
0
- (void)pageViewController:(UIPageViewController *)pageViewController didFinishAnimating:(BOOL)finished previousViewControllers:(NSArray *)previousViewControllers transitionCompleted:(BOOL)completed {

    NSLog(@"Current Page = %@", pageViewController.viewControllers);

    UIViewController *currentView = [pageViewController.viewControllers objectAtIndex:0];

    if ([currentView isKindOfClass:[FirstPageViewController class]]) {
             NSLog(@"First View");
        }
        else if([currentView isKindOfClass:[SecondPageViewController class]]) {
             NSLog(@"Second View");
        }
        else if([currentView isKindOfClass:[ThirdViewController class]]) {
              NSLog(@"Third View");
        }
}

//pageViewController.viewControllers always return current visible View ViewController
avinash
fuente
0

Debajo del código de demostración (en Swift 2) que demuestra cómo se hace esto mediante la implementación de un sencillo tutorial de deslizamiento de imágenes. Comentarios en el propio código:

import UIKit

/*
VCTutorialImagePage represents one page show inside the UIPageViewController.
You should create this page in your interfacebuilder file:
- create a new view controller
- set its class to VCTutorialImagePage
- sets its storyboard identifier to "VCTutorialImagePage" (needed for the loadView function)
- put an imageView on it and set the contraints (I guess to top/bottom/left/right all to zero from the superview)
- connect it to the "imageView" outlet
*/

class VCTutorialImagePage : UIViewController {
    //image to display, configure this in interface builder
    @IBOutlet weak var imageView: UIImageView!
    //index of this page
    var pageIndex : Int = 0

    //loads a new view via the storyboard identifier
    static func loadView(pageIndex : Int, image : UIImage) -> VCTutorialImagePage {
        let storyboard = UIStoryboard(name: storyBoardHome, bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier("VCTutorialImagePage") as! VCTutorialImagePage
        vc.imageView.image      = image
        vc.pageIndex            = pageIndex
        return vc
    }
}


/*
VCTutorialImageSwiper takes an array of images (= its model) and displays a UIPageViewController 
where each page is a VCTutorialImagePage that displays an image. It lets you swipe throught the 
images and will do a round-robbin : when you swipe past the last image it will jump back to the 
first one (and the other way arround).

In this process, it keeps track of the current displayed page index
*/

class VCTutorialImageSwiper: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    //our model = images we are showing
    let tutorialImages : [UIImage] = [UIImage(named: "image1")!, UIImage(named: "image2")!,UIImage(named: "image3")!,UIImage(named: "image4")!]
    //page currently being viewed
    private var currentPageIndex : Int = 0 {
        didSet {
            currentPageIndex=cap(currentPageIndex)
        }
    }
    //next page index, temp var for keeping track of the current page
    private var nextPageIndex : Int = 0


    //Mark: - life cylce


    override func viewDidLoad() {
        super.viewDidLoad()
        //setup page vc
        dataSource=self
        delegate=self
        setViewControllers([pageForindex(0)!], direction: .Forward, animated: false, completion: nil)
    }


    //Mark: - helper functions

    func cap(pageIndex : Int) -> Int{
        if pageIndex > (tutorialImages.count - 1) {
            return 0
        }
        if pageIndex < 0 {
            return (tutorialImages.count - 1)
        }
        return pageIndex
    }

    func carrouselJump() {
        currentPageIndex++
        setViewControllers([self.pageForindex(currentPageIndex)!], direction: .Forward, animated: true, completion: nil)
    }

    func pageForindex(pageIndex : Int) -> UIViewController? {
        guard (pageIndex < tutorialImages.count) && (pageIndex>=0) else { return nil }
        return VCTutorialImagePage.loadView(pageIndex, image: tutorialImages[pageIndex])
    }

    func indexForPage(vc : UIViewController) -> Int {
        guard let vc = vc as? VCTutorialImagePage else {
            preconditionFailure("VCPagImageSlidesTutorial page is not a VCTutorialImagePage")
        }
        return vc.pageIndex
    }


    //Mark: - UIPageView delegate/datasource


    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        return pageForindex(cap(indexForPage(viewController)+1))
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        return pageForindex(cap(indexForPage(viewController)-1))
    }

    func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) {
        nextPageIndex = indexForPage(pendingViewControllers.first!)
    }

    func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
        if !finished { return }
        currentPageIndex = nextPageIndex
    }

    func presentationCountForPageViewController(pageViewController: UIPageViewController) -> Int {
        return tutorialImages.count
    }

    func presentationIndexForPageViewController(pageViewController: UIPageViewController) -> Int {
        return currentPageIndex
    }

}
HixField
fuente
0

Tengo una matriz viewControllers, que muestro en UIPageViewController .

extension MyViewController: UIPageViewControllerDataSource {

func presentationCount(for pageViewController: UIPageViewController) -> Int {
    return self.viewControllers.count
}

func presentationIndex(for pageViewController: UIPageViewController) -> Int {
    return self.currentPageIndex
}
}




extension MyViewController: UIPageViewControllerDelegate {

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {

    if !completed { return }

    guard let viewController = previousViewControllers.last, let index = indexOf(viewController: viewController) else {
        return
    }

    self.currentPageIndex = index

}

fileprivate func indexOf(viewController: UIViewController) -> Int? {
    let index = self.viewControllers.index(of: viewController)
    return index
}
}

Lo importante a destacar aquí es que el setViewControllers método de UIPageViewController no da ninguna devolución de llamada delegado. Las devoluciones de llamada delegadas solo representan acciones táctiles del usuario en UIPageViewController .

jarora
fuente
0

Esta es la solución que se me ocurrió:

class DefaultUIPageViewControllerDelegate: NSObject, UIPageViewControllerDelegate {

    // MARK: Public values
    var didTransitionToViewControllerCallback: ((UIViewController) -> Void)?

    // MARK: Private values
    private var viewControllerToTransitionTo: UIViewController!

    // MARK: Methods
    func pageViewController(
        _ pageViewController: UIPageViewController,
        willTransitionTo pendingViewControllers: [UIViewController]
    ) {
        viewControllerToTransitionTo = pendingViewControllers.last!
    }

    func pageViewController(
        _ pageViewController: UIPageViewController,
        didFinishAnimating finished: Bool,
        previousViewControllers: [UIViewController],
        transitionCompleted completed: Bool
    ) {
        didTransitionToViewControllerCallback?(viewControllerToTransitionTo)
    }
}

Uso:

 let pageViewController = UIPageViewController()
 let delegate = DefaultUIPageViewControllerDelegate()

 delegate.didTransitionToViewControllerCallback = {
    pageViewController.title = $0.title
 }

 pageViewController.title = viewControllers.first?.title
 pageViewController.delegate = delegate

Asegúrese de establecer el título inicial

Peter Combee
fuente
0

La forma más sencilla de abordar este IMHO es utilizar el PageControl para almacenar el resultado potencial de la transición y luego revertir si la transición se canceló. Esto significa que el control de la página cambia tan pronto como el usuario comienza a deslizar, lo cual está bien para mí. Esto requiere que tenga su propia matriz de UIViewControllers (en este ejemplo llamado allViewControllers)

func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
    if let index = self.allViewControllers.index(of: pendingViewControllers[0]) {
        self.pageControl.currentPage = index
    }
}

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    if !completed, let previousIndex = self.allViewControllers.index(of: previousViewControllers[0]) {
        self.pageControl.currentPage = previousIndex
    }
}
Taylor Swift
fuente
0

¿Qué tal pedir un viewControllerdirectamente desde la UIPageViewController(versión Swift 4):

fileprivate weak var currentlyPresentedVC: UIViewController?

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    currentlyPresentedVC = pageViewController.viewControllers?.first
}

O, si solo necesita el controlador de vista presentado actualmente en algún momento, simplemente úselo pageViewController.viewControllers?.firsten ese momento.

Milán Nosáľ
fuente
0

En Swift 5 y la siguiente respuesta de Sirvine

extension InnerDetailViewController: UIPageViewControllerDelegate {

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {

        if completed {
            guard let newIndex = embeddedViewControllers.firstIndex(where: { $0 == pageViewController.viewControllers?.last }) else { return }
            print(newIndex)
            currentEmbeddedViewControllerIndex = newIndex
        }

    }

} 

En este caso, no me importa qué clase de UIViewController están incrustados

Reimond Hill
fuente
-1
UIViewController *viewController = [pageViewController.viewControllers objectAtIndex:0];
NSUInteger currentIndex = [(ViewController*) viewController indexNumber];

Devolverá el índice de la página actual. y debe usar este código bajo la función delegada de UIPageViewController (didFinishAnimating).

Vinay Podili
fuente