2017-02-24 2 views
0

Ich habe einen PageViewController, der zwei "untergeordnete" ViewControllers lädt, damit der Benutzer durch sie "wischen" kann. Ich möchte diese Wischgeste nicht, aber stattdessen möchte ich eine Funktion in meinem ViewController haben, mit der ich setViewControllers im PageViewController verwenden kann.Swift: Aufruf der Funktion in PageViewController von einem anderen Viewcontroller

Ich versuchte mit Protokollen, aber selbst das hat nicht geklappt.

Ich würde wirklich jede Hilfe oder Vorschläge schätzen, wie ich das erreichen könnte. Vielen Dank!

Antwort

1

Um setViewControllers zugreifen Von den untergeordneten Ansichtscontrollern müssen die untergeordneten Ansichtscontroller auf ihren übergeordneten PageViewController achten. Beginnen Sie dazu mit dem Erstellen eines Protokolls (ich weiß, Sie haben gesagt, Sie haben Protokolle ausprobiert, aber bitte sehen Sie meine Methode durch). Dieses Protokoll stellt sicher, dass jeder untergeordnete Ansichtscontroller einen Verweis auf den übergeordneten PageViewController hat.

Stellen Sie sicher, dass Ihre untergeordneten Ansichtscontroller das PageObservation Protocol einhalten.

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

In Ihrem PageViewController, wie Sie jedes Kind-View-Controller zu erstellen, warf sie auf den PageObservation Typ und eine Referenz des Mutter PageViewController passieren. Ich verwende ein Array namens orderViewControllers, um meine Seiten zu erstellen. Meine UIPageViewControllerDataSource-Delegatmethoden verwenden diese, um zu wissen, welche Seiten geladen werden sollen, aber das ist für dieses Beispiel irrelevant. Ich dachte nur, ich würde Sie darüber informieren, falls Sie Ihre Seiten auf andere Weise erstellen.

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) 
    } 

Jetzt in Ihrem Kind View-Controller haben Sie Zugriff auf setViewControllers.Zum Beispiel, wenn ich setViewControllers im child1ViewController nennen wollen, habe ich eine func genannt accessSetViewControllers() erstellt, wo ich die setViewControllers Zugang:

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

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

Auf einer Seite zur Kenntnis, ungeachtet dessen, was andere Antworten oben gesagt haben, können Sie Setzen Sie dataSource auf was auch immer Sie möchten. Ich setze manchmal dataSource auf Null, um zu verhindern, dass der Benutzer von einem Bildschirm wegwischt, bevor er etwas unternimmt, und fügt dann die dataSource zurück, damit sie weiter wischen können.

+0

Danke für Ihre Antwort. Aber was ist "pageViewController" in Ihrem Code? Sie verwenden es beim Erstellen der untergeordneten Controller. –

+0

Es war ein Fehler, sorry. Ich habe es jetzt korrigiert. – gwinyai

+0

Ich habe deine Lösung versucht und alles scheint zu funktionieren! Bei weitem die beste Antwort online gefunden! Allerdings habe ich noch eine Frage: Nehmen wir an, ich habe 3 Child View Controller und jeder von ihnen ist in einem eigenen Navigation Controller eingebettet. Wie kann ich dann die Kindercontroller erstellen? Nur mit dem Navigation Controller - Storyboard - ID zu arbeiten, hat nicht funktioniert. Muss ich noch etwas ändern? Mit freundlichen Grüßen und große Danke! –

0

Nicht dataSource einstellen. Wenn es nichts ist, funktionieren Gesten nicht.

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

Wenn eine Seite-View-Controller-Schnittstelle definiert, können Sie die Ansicht Controller Inhalts bereitstellen einen nach dem anderen (oder zwei zu einer Zeit, abhängig von der Position der Wirbelsäule und doppelseitigem Zustand) oder als benötigt eine Datenquelle. Wenn Sie Inhaltsansichts-Controller nacheinander bereitstellen, verwenden Sie die Methode setViewControllers(_:direction:animated:completion:), um die aktuellen Inhaltsansicht-Controller festzulegen. Um die gestenbasierte Navigation zu unterstützen, müssen Sie Ihre View-Controller mithilfe eines Datenquellenobjekts bereitstellen.

+0

Ja, ich habe darüber gelesen. Das Problem ist, dass ich nicht weiß, wie ich "setViewControllers" von meinem Kind ViewControllers aufrufen soll. Anyways, danke für die Antwort –

+0

Es wäre besser, wenn Sie ein Delegate-Protokoll mit Methoden wie 'goBack' /' goForward' erstellen und eine schwache Eigenschaft für den Delegaten zu Ihren untergeordneten VCs hinzufügen. Danach machen Sie Ihren Eltern-VC zum Delegaten Ihrer Kind-VCs. In diesem Fall müssen Sie 'setViewControllers' von Kindern nicht direkt aufrufen und sie werden nichts über die Seite VC wissen. – Dmitry

+0

Ich werde das versuchen! Vielleicht funktioniert es, wenn es so ist, bist du wirklich ein Leben sicherer! –

0

Simplistic Ansatz ... entfernen Sie die eingebaute Geste Erkenner in viewDidLoad von pageViewController:

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

Dann unten, damit er Ihre eigene Geste hinzuzufügen. Ich war zufällig gerade mit doppeltem Hahn im Moment zu arbeiten, aber man kann es links machen Swipe, wischen Sie nach rechts leicht genug:

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

und der Geste Funktion mit Ihrem Code:

func didDoubleTap(gesture: UITapGestureRecognizer) { 

//... stuff 

} 
Verwandte Themen