Swift:从其他视图控制器调用 PageViewController 中的函数
Posted
技术标签:
【中文标题】Swift:从其他视图控制器调用 PageViewController 中的函数【英文标题】:Swift: Call Function in PageViewController from other Viewcontroller 【发布时间】:2017-02-24 01:17:34 【问题描述】:我有一个 PageViewController,它加载两个“子”ViewController,以便让用户“滑动”它们。我不想要这种滑动手势,而是希望在我的 ViewController 中有一个函数,它允许我在 PageViewController 中使用 setViewControllers。
我尝试使用协议,但即使这样也没有成功。
对于如何实现这一点,我非常感谢任何帮助或建议。谢谢!
【问题讨论】:
【参考方案1】:要从您的子视图控制器访问 setViewController,您需要您的子视图控制器知道它们的父 PageViewController。要做到这一点,首先要制定一个协议(我知道你说过你已经尝试过协议,但请看我的方法)。该协议将确保每个子视图控制器都有对父 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,我创建了一个名为 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 添加回来以允许他们继续滑动。
【讨论】:
感谢您的回答。但是您的代码中的“pageViewController”是什么?您在创建子控制器时使用它。 我尝试了您的解决方案,似乎一切正常!迄今为止在网上找到的最佳答案!但是,我还有一个问题:假设我有 3 个子视图控制器,每个子视图控制器都嵌入在自己的导航控制器中。那么如何“创建子控制器”呢?仅使用 Navigation Controller - Storyboard - ID 引用它们不起作用。我是否必须更改其他内容?最好的问候,非常感谢! 如果我理解正确的话,您有一个 PageViewController 和三个孩子,但每个孩子都有自己的导航控制器,对吧?您不需要引用导航控制器来创建子项。您只需要给孩子一个标识符并从中实例化它,孩子就会知道它自己有一个导航控制器。对于具有标识符“child”但嵌入在导航控制器中的孩子,您可以这样做: let childVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "child") as! ChildViewController 我今天尝试了您的建议,但无法正常运行。应用程序因 Signal 1 Sigabrt 或奇怪的展开错误而崩溃。你能给我一个工作示例吗?我真的很感激。很抱歉我一直在问我的问题,但我对 Swift 还很陌生,但我仍在努力学习很多东西! 很乐意提供帮助,但也许我是不了解您想要实现的目标的人。我认为最好将这个问题作为一个问题放在 Stack 上,我或任何人都可以尝试回答它。一些提示:如果可能,添加图表,添加您已经尝试但不起作用的代码,提及 Stack 上任何不适合您的解决方案。【参考方案2】:不要设置dataSource
。当它为 nil 时,手势将不起作用。
https://developer.apple.com/reference/uikit/uipageviewcontroller
定义页面视图控制器接口时,您可以一次提供一个(或一次提供两个,取决于书脊位置和双面状态)或使用数据源按需提供内容视图控制器。当一次提供一个内容视图控制器时,您使用
setViewControllers(_:direction:animated:completion:)
方法来设置当前的内容视图控制器。 要支持基于手势的导航,您必须使用数据源对象提供视图控制器。
【讨论】:
是的,我已经读过。问题是,我不知道如何从我的子 ViewControllers 中调用“setViewControllers”。不管怎样,谢谢你的回复 如果您使用goBack
/goForward
之类的方法创建一个委托协议并为您的子VC添加一个弱属性会更好。之后,让您的父 VC 成为您子 VC 的代表。在这种情况下,您不需要直接从孩子那里致电setViewControllers
,他们不会知道任何关于 Page VC 的信息
我会试试的!也许它有效,如果它这样做,你真的是一个更安全的生活!【参考方案3】:
简单的方法...删除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
【讨论】:
以上是关于Swift:从其他视图控制器调用 PageViewController 中的函数的主要内容,如果未能解决你的问题,请参考以下文章