J'essaie d'utiliser une UIPageViewController
dans une application Swift avec plusieurs contrôleurs de vue. J'ai 2 contrôleurs de vue sur mon scénario (firstViewController
et secondViewController
) qui sont tous deux intégrés dans leurs propres contrôleurs de navigation. Ils ont des identifiants de storyboard "FirstViewController
" et "SecondViewController
". J'ai également un contrôleur de vue de page sur mon storyboard avec le contrôleur identifierPageView
et je règle la navigation sur horizontal et le style de transition pour faire défiler l'inspecteur d'attributs. FirstViewController
est le contrôleur de vue racine de l'application
Je veux que firstViewController
soit la première page du contrôleur de vue de page, de sorte que j'ai écrit sa classe comme suit:
import Foundation
import UIKit
class FirsttViewController: UITableViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
override func viewDidLoad() {
let pageViewController: PageViewController = self.storyboard.instantiateViewControllerWithIdentifier("PageViewController") as PageViewController
pageViewController.delegate = self
var viewControllers: [UIViewController] = [self]
pageViewController.setViewControllers(viewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
pageViewController.view.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
self.addChildViewController(pageViewController)
self.view.addSubview(pageViewController.view)
pageViewController.didMoveToParentViewController(self)
}
func pageViewController(pageViewController: UIPageViewController!, viewControllerAfterViewController viewController: UIViewController!) -> UIViewController! {
let secondViewController: SecondViewController = self.storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as SecondViewController
return secondViewController
}
func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {
return nil
}
func presentationCountForPageViewController(pageViewController: UIPageViewController!) -> Int {
return 2
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController!) -> Int {
return 0
}
}
le fichier pour SecondViewController
ressemble à ceci:
import Foundation
import UIKit
class SecondViewController: UITableViewController, UIPageViewControllerDataSource {
func pageViewController(pageViewController: UIPageViewController!, viewControllerAfterViewController viewController: UIViewController!) -> UIViewController! {
return nil
}
func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {
let firstViewController: FirstViewController = self.storyboard.instantiateViewControllerWithIdentifier("FirstViewController") as FirstViewController
return firstViewController
}
}
Cependant, lorsque je lance mon application, elle ne semble pas avoir de contrôleur de visualisation de page. Il montre simplement firstViewController
et c'est tout. Pas de points, pas de pages, etc. Quelqu'un sait ce qui ne va pas? J'ai trouvé quelques didacticiels Objective-C, mais ils traitent tous de l'utilisation d'un seul contrôleur de vue pour toutes les pages et ont un contrôleur de vue racine qui n'est pas une page dans la variable pageView
. J'espérais que cela ressemblerait à l'utilisation d'une tabBarController
dans laquelle vous cliqueriez et glisseriez sur les contrôleurs de vue, mais ce n'est malheureusement pas le cas. Comme je l'ai dit, je n'ai jamais travaillé avec l'un de ces appareils auparavant, alors je suis un peu perdu.
suivant la suggestion de iiFreeman, j’ai sous-classé UIPageViewController
et en ai fait la racine de mon fichier de storyboard. ci-dessous est la sous-classe
import Foundation
import UIKit
class PageViewController: UIPageViewController {
override func viewDidLoad() {
let startingViewController = self.storyboard.instantiateViewControllerWithIdentifier("FirstViewController") as FirstViewController
self.dataSource = startingViewController
var viewControllers: [UIViewController] = [startingViewController]
self.setViewControllers(viewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
}
Cependant, l’application se bloque maintenant sur un écran noir et finalement, Xcode perd la connexion au simulateur. Je ne suis pas vraiment sûr de ce qui se passe.
OK, j'ai compris. Comme j'avais besoin du contrôleur de vue de page pour être la racine et tout gérer, j'ai sous-classé UIPageViewController
comme iiFreeman a suggéré et conforme aux protocoles de délégué et de source de données. J'ai ensuite configuré le contrôleur dans viewDidLoad
et mis en œuvre les méthodes de délégué et de source de données. J'ai ajouté à un magasin de propriétés un tableau d'identifiants de storyboard ainsi qu'un autre permettant de suivre l'index actuel de ce tableau. J'ai également ajouté une méthode d'assistance pour renvoyer le bon contrôleur de vue à partir d'un index. Je n'avais besoin de rien dans mes autres sous-classes de contrôleur tableView
puisque mon contrôleur d'affichage de page gérait tout. Une chose que j’ai réalisée c’est que, puisque ma tableViewController
s était intégrée à des contrôleurs de navigation, mon contrôleur de visualisation de page devait afficher les contrôleurs de navigation, et non les contrôleurs tableView
. ci-dessous est ma mise en œuvre:
import Foundation
import UIKit
class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {
var index = 0
var identifiers: NSArray = ["FirstNavigationController", "SecondNavigationController"]
override func viewDidLoad() {
self.dataSource = self
self.delegate = self
let startingViewController = self.viewControllerAtIndex(self.index)
let viewControllers: NSArray = [startingViewController]
self.setViewControllers(viewControllers, direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)
}
func viewControllerAtIndex(index: Int) -> UINavigationController! {
//first view controller = firstViewControllers navigation controller
if index == 0 {
return self.storyboard.instantiateViewControllerWithIdentifier("FirstNavigationController") as UINavigationController
}
//second view controller = secondViewController's navigation controller
if index == 1 {
return self.storyboard.instantiateViewControllerWithIdentifier("SecondNavigationController") as UINavigationController
}
return nil
}
func pageViewController(pageViewController: UIPageViewController!, viewControllerAfterViewController viewController: UIViewController!) -> UIViewController! {
let identifier = viewController.restorationIdentifier
let index = self.identifiers.indexOfObject(identifier)
//if the index is the end of the array, return nil since we dont want a view controller after the last one
if index == identifiers.count - 1 {
return nil
}
//increment the index to get the viewController after the current index
self.index = self.index + 1
return self.viewControllerAtIndex(self.index)
}
func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {
let identifier = viewController.restorationIdentifier
let index = self.identifiers.indexOfObject(identifier)
//if the index is 0, return nil since we dont want a view controller before the first one
if index == 0 {
return nil
}
//decrement the index to get the viewController before the current one
self.index = self.index - 1
return self.viewControllerAtIndex(self.index)
}
func presentationCountForPageViewController(pageViewController: UIPageViewController!) -> Int {
return self.identifiers.count
}
func presentationIndexForPageViewController(pageViewController: UIPageViewController!) -> Int {
return 0
}
}
sure cause FirstViewController - contrôleur de vue initial dans votre storyboard
ajoutez une sous-classe UIPageViewController personnalisée dans votre story-board, marquez-la comme initiale et faites tout le travail à l'intérieur, instanciez les membres du contrôleur de page par des storyboard dans votre sous-classe UIPageViewController, faites la même chose dans une autre classe
Sachez que ce code ne fonctionnera qu'avec deux ViewController
. Si vous envisagez d’utiliser davantage, vous devez modifier la ligne:
self.index = self.index + 1
Trouvé à l'avant et après l'appel, à:
self.index = index + 1
Pour appeler l'index ViewController
actuel.