2017-02-24 59 views
0

我得到了一個PageViewController,它加載兩個「子」ViewControllers以讓用戶「滑過」它們。我不想要這種輕掃手勢,但我想在我的ViewController中有一個函數,它允許我在PageViewController中使用setViewController。Swift:從其他ViewController調用PageViewController中的函數

我試過使用協議,但即使這樣也沒有解決。

我真的很感謝任何幫助或建議,我怎麼能做到這一點。謝謝!

回答

1

要訪問setViewControllers從您的子視圖控制器中,您將需要您的子視圖控制器瞭解其父級PageViewController。要做到這一點,首先制定一個協議(我知道你說過你已經試過了協議,但請看看我的方法)。該協議將確保每個子視圖控制器都具有對父頁面控制器的引用。

protocol PageObservation: class { 
     func getParentPageViewController(parentRef: PageViewController) 
    } 

確保您的子視圖控制器遵守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 
     } 
    } 

在你PageViewController,爲您塑造每個子視圖控制器,摔在PageObservation類型,並通過父PageViewController的參考。我使用一個名爲orderViewControllers的數組來創建我的頁面。我的UIPageViewControllerDataSource委託方法使用它來知道要加載哪些頁面,但與此示例無關,我只是想讓我知道如果您有不同的創建頁面的方式。

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

現在在您的子視圖控制器中,您可以訪問setViewControllers。例如,如果我想打電話給在child1ViewController setViewControllers,我創建了一個FUNC稱爲accessSetViewControllers(),我訪問setViewControllers:

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

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

在一個側面說明,儘管有什麼其他的答案上面已經說過,你可以將dataSource設置爲任何你喜歡的。我有時將dataSource設置爲nil,以防止用戶在做某件事之前從屏幕上滑開,然後添加dataSource以允許它們繼續滑動。

+0

感謝您的回答。但是,代碼中的「pageViewController」是什麼?您在創建子控制器時正在使用它。 –

+0

這是一個錯誤,抱歉。我現在糾正了它。 – gwinyai

+0

我試過你的解決方案,一切似乎工作!到目前爲止在網上找到最好的答案! 不過,我有一個問題: 比方說,我有3個孩子視圖控制器和他們每個人在自己的導航控制器內嵌被。那麼如何「創建子控制器」?只有使用導航控制器 - 故事板 - ID引用它們才能起作用。我需要改變別的東西嗎? 此致敬禮,大謝謝! –

0

請勿設置dataSource。當它爲零時,手勢將不起作用。

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

當定義一個頁面視圖控制器接口,可以提供的內容視圖控制器一次一個(或兩個的時間,這取決於脊柱位置和雙面狀態)或作爲 - 需要使用數據源。一次提供一個內容視圖控制器時,您可以使用setViewControllers(_:direction:animated:completion:)方法來設置當前內容視圖控制器。 要支持基於姿勢的導航,您必須使用數據源對象提供視圖控制器。

+0

是的,我已經閱讀有關。問題是,我不知道如何從我的子ViewControllers調用「setViewControllers」。 不管怎麼說,感謝回答 –

+0

如果你創建喜歡'goBack' /'goForward'方法委託協議和委託弱屬性添加到您的孩子的風險投資會更好。之後,讓你的家長VC代表你的孩子VC。在這種情況下,你不需要直接從子節點調用setViewControllers,他們也不會知道任何有關Page VC – Dmitry

+0

我會嘗試!也許它是有效的,如果是這樣的話,你真的是一個安全的生活! –

0

簡單的方法......取下內置手勢識別器在pageViewController的viewDidLoad中:

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

然後在它下面添加你自己的姿態。我正好就在此刻與雙擊工作,但你可以把它向左滑動,向右滑動,即可很容易的:

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

,並與您的代碼手勢功能:

func didDoubleTap(gesture: UITapGestureRecognizer) { 

//... stuff 

}