Swift:从其他ViewController调用PageViewController中的函数

问题描述:

我得到了一个PageViewController,它加载两个“子”ViewControllers以让用户“滑过”它们。我不想要这种轻扫手势,但我想在我的ViewController中有一个函数,它允许我在PageViewController中使用setViewController。Swift:从其他ViewController调用PageViewController中的函数

我试过使用协议,但即使这样也没有解决。

我真的很感谢任何帮助或建议,我怎么能做到这一点。谢谢!

要访问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引用它们才能起作用。我需要改变别的东西吗? 此致敬礼,大谢谢! –

请勿设置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

我会尝试!也许它是有效的,如果是这样的话,你真的是一个安全的生活! –

简单的方法......取下内置手势识别器在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 

}