2017-02-24 5 views
0

J'ai un PageViewController qui charge deux ViewController "enfants" afin de permettre à l'utilisateur de les "glisser". Je ne veux pas ce geste de balayage, mais je veux plutôt avoir une fonction dans mon ViewController qui me permet d'utiliser setViewControllers dans le PageViewController.Swift: Fonction d'appel dans PageViewController à partir d'un autre Viewcontroller

J'ai essayé d'utiliser des protocoles, mais même cela n'a pas fonctionné.

J'apprécierais vraiment n'importe quelle aide ou suggestions sur la façon dont je pourrais accomplir cela. Merci!

Répondre

1

Pour accéder setViewControllers À partir de vos contrôleurs de vue enfant, vous aurez besoin de vos contrôleurs de vue enfant pour connaître leur PageViewController parent. Pour ce faire, commencez par faire un protocole (je sais que vous avez dit que vous avez essayé les protocoles, mais s'il vous plaît, veuillez voir ma méthode). Ce protocole garantit que chaque contrôleur de vue enfant a une référence au PageViewController parent. Assurez-vous que les contrôleurs de vue enfants respectent le protocole PageObservation.

class Child1ViewController: UIViewController, PageObservation { 
     var parentPageViewController: PageViewController! 
     func getParentPageViewController(parentRef: PageViewController) { 
      parentPageViewController = parentRef 
     } 
    } 

    class Child2ViewController: UIViewController, PageObservation { 
     var parentPageViewController: PageViewController! 
     func getParentPageViewController(parentRef: PageViewController) { 
      parentPageViewController = parentRef 
     } 
    } 

Dans votre PageViewController, que vous créez chaque contrôleur de vue des enfants, les jeter au type de PageObservation et passer une référence de la PageViewController mère. J'utilise un tableau appelé orderViewControllers pour créer mes pages. Mes méthodes de délégué UIPageViewControllerDataSource l'utilise pour savoir quelles pages charger mais ce n'est pas pertinent pour cet exemple, je pensais juste que je vous le ferais savoir au cas où vous auriez une manière différente de créer vos pages.

class PageViewController: UIPageViewController { 
     var orderedViewControllers: [UIViewController] = [] 


     //creating child 1 
     //i am using storyboard to create the child view controllers, I have given them the identifiers Child1ViewController and Child2ViewController respectively 
     let child1ViewController = UIStoryboard(name: "Main", bundle: nil) . 
     instantiateViewController(withIdentifier: "Child1ViewController") 
     let child1WithParent = child1ViewController as! PageObservation 
     child1WithParent.getParentPageViewController(parentRef: self) 

     orderedViewControllers.append(child1ViewController) 

     //creating child 2 
     let child2ViewController = UIStoryboard(name: "Main", bundle: nil) . 
     instantiateViewController(withIdentifier: "Child2ViewController") 
     let child2WithParent = child2ViewController as! PageObservation 
     child2WithParent.getParentPageViewController(parentRef: self) 

     orderedViewControllers.append(child2ViewController) 
    } 

Maintenant, dans votre contrôleur enfant, vous avez accès à setViewControllers.Par exemple, si je veux appeler setViewControllers dans le child1ViewController, j'ai créé un fonc appelé accessSetViewControllers() où j'accéder aux setViewControllers:

class Child1ViewController: UIViewController, PageObservation { 
     var parentPageViewController: PageViewController! 
     func getParentPageViewController(parentRef: PageViewController) { 
      parentPageViewController = parentRef 
     } 

     func accessSetViewControllers() { 
      parentPageViewController.setViewControllers(//do what you need) 
     } 
    } 

Sur une note de côté, malgré ce que les autres réponses ci-dessus ont dit, vous pouvez Définissez dataSource comme vous le souhaitez. Il m'arrive de mettre la valeur de dataSource à zéro pour empêcher l'utilisateur de quitter un écran avant de faire quelque chose, puis d'ajouter à nouveau dataSource pour leur permettre de continuer à balayer.

+0

Merci pour votre réponse. Mais qu'est ce que "pageViewController" dans votre code? Vous l'utilisez lors de la création des contrôleurs enfants. –

+0

C'était une erreur, désolé. Je l'ai corrigé maintenant. – gwinyai

+0

J'ai essayé votre solution et tout semble fonctionner! De loin la meilleure réponse trouvée en ligne! Cependant, j'ai une question: Disons que j'ai 3 contrôleurs Voir l'enfant et chacun d'eux est embeded dans leur propre contrôleur de navigation. Comment puis-je "créer les contrôleurs enfants" alors? Se référer uniquement à eux avec le contrôleur de navigation - Storyboard - ID n'a pas fonctionné. Dois-je changer autre chose? Meilleures salutations, et grand merci! –

0

Ne pas définir dataSource. Quand c'est nul, alors les gestes ne fonctionneront pas.

https://developer.apple.com/reference/uikit/uipageviewcontroller

Lors de la définition d'une interface de contrôleur d'affichage de la page, on peut prévoir l'affichage du contenu de commande un par un (ou deux à la fois, en fonction de la position de la colonne vertébrale et de l'état recto-verso) ou -deeded en utilisant une source de données. Lorsque vous fournissez des contrôleurs de vue de contenu un à la fois, vous utilisez la méthode setViewControllers(_:direction:animated:completion:) pour définir les contrôleurs de vue de contenu actuels. Pour prendre en charge la navigation basée sur les gestes, vous devez fournir vos contrôleurs de vue à l'aide d'un objet de source de données.

+0

Oui, j'ai lu à ce sujet. Le problème est que je ne sais pas comment appeler "setViewControllers" depuis mon ViewControllers enfant. Quoi qu'il en soit, merci pour la réponse –

+0

Il serait préférable si vous créez un protocole de délégué avec des méthodes comme 'goBack' /' goForward' et ajoutez une propriété faible pour le délégué à vos VCs enfants. Après cela, faites de votre VC parent le délégué aux VCs de votre enfant. Dans ce cas, vous n'avez pas besoin d'appeler 'setViewControllers' d'enfants directement et ils ne sauront pas quoi que ce soit au sujet de la page VC – Dmitry

+0

je vais essayer! Peut-être que cela fonctionne, si c'est le cas, vous êtes vraiment une vie plus sûre! –

0

simplisme ... supprimer le geste de reconnaissance intégré dans viewDidLoad de pageViewController:

for view in self.pageViewController!.view.subviews { 
    if let subView = view as? UIScrollView { 
     subView.scrollEnabled = false 
    } 
} 

Ajoutez ensuite votre propre geste en dessous. Je suis tombé à travailler avec double prise au moment mais vous pouvez le faire glisser vers la gauche, glisser vers la droite assez facile:

let doubleTap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(didDoubleTap)) 
doubleTap.numberOfTapsRequired = 2 
doubleTap.delaysTouchesBegan = true 
self.addGestureRecognizer(doubleTap) 

et la fonction de geste avec votre code:

func didDoubleTap(gesture: UITapGestureRecognizer) { 

//... stuff 

}