web-dev-qa-db-fra.com

Actualiser UIPageViewController - réorganiser les pages et ajouter de nouvelles pages

J'ai un UIPageViewController auquel je fournis des données de page pour utiliser une implémentation de UIPageControllerDelegate et UIPageControllerDataSource.

Tout fonctionne bien, mais je veux pouvoir ajouter des éléments aux données de la page et réorganiser les données de la page.

Si un utilisateur a déjà accédé à la dernière des pages et que j'ajoute un élément, il ne peut pas accéder à la page suivante car viewControllerAfterViewController: a déjà été appelé. S'ils font défiler un, puis deux, ils peuvent accéder à la nouvelle page sans problème, de sorte que les données sont configurées correctement. Comment puis-je dire à la UIPageViewController de rafraîchir sa mémoire de ce qui va suivre?

De même, j'aimerais réorganiser la collection qui sauvegarde la vue de page. Mais si je fais cela, j'aurai le même problème: la page consultée pensera que la page suivante est toujours celle qui était la dernière fois que la page actuelle a été chargée.

Je suppose que je recherche quelque chose de similaire à reloadData: sur UITableView.

33
ssloan

Vous devez appeler setViewControllers:direction:animated:completion:.

De plus, dans iOS 6, surveillez si vous utilisez le style UIPageViewControllerTransitionStyleScroll, car il existe un bogue majeur de mise en cache si animated: est défini sur YES (voir ma discussion ici: UIPageViewController navigue vers une page incorrecte avec le style de transition Scroll ).

27
matt

J'ai trouvé une solution de contournement pour forcer UIPageViewController à oublier les contrôleurs de vue en cache des pages voisines actuellement non affichées:

pageViewController.dataSource = nil;
pageViewController.dataSource = self;

Je le fais chaque fois que je change l'ensemble des pages. Bien sûr, cela n’affecte pas la page actuellement affichée.

Avec cette solution de contournement, j'évite le bogue de mise en cache et peux toujours utiliser animated:YES dans setViewControllers:direction:animated:completion:.

85
Ortwin Gentz

Voici ma mise en œuvre complète de la réponse de @ ortwin-gentz dans la méthode du délégué didFinish dans Swift 2, qui fonctionne parfaitement pour moi:

func pageViewController(
    pageViewController: UIPageViewController,
    didFinishAnimating finished: Bool,
    previousViewControllers: [UIViewController],
    transitionCompleted completed: Bool
) {
    if !completed { return }
    dispatch_async(dispatch_get_main_queue()) {
        pageViewController.dataSource = nil
        pageViewController.dataSource = self
    }
}
3
theory

Swift 4 Version pour recharger les données de pageviewcontroller vers la version de @ theory.

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
    if !completed { return }
    DispatchQueue.main.async() {
        self.dataSource = nil
        self.dataSource = self
    }
}
0
Parion