Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift:从其他Viewcontroller调用PageViewController中的函数_Ios_Swift_Xcode_Delegates_Uipageviewcontroller - Fatal编程技术网

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

Ios Swift:从其他Viewcontroller调用PageViewController中的函数,ios,swift,xcode,delegates,uipageviewcontroller,Ios,Swift,Xcode,Delegates,Uipageviewcontroller,我得到了一个PageViewController,它加载两个“子”ViewController,以便让用户“滑动”它们。我不想要这个滑动手势,但是我想在我的ViewController中有一个函数,允许我在PageViewController中使用SetViewController 我试着使用协议,但即使这样也没有成功 我真的非常感谢您对我如何做到这一点的任何帮助或建议。谢谢 不要设置数据源。当它为零时,手势就不起作用了 定义页面视图控制器界面时,可以一次提供一个内容视图控制器(或一次提供两个

我得到了一个PageViewController,它加载两个“子”ViewController,以便让用户“滑动”它们。我不想要这个滑动手势,但是我想在我的ViewController中有一个函数,允许我在PageViewController中使用SetViewController

我试着使用协议,但即使这样也没有成功


我真的非常感谢您对我如何做到这一点的任何帮助或建议。谢谢

不要设置
数据源
。当它为零时,手势就不起作用了

定义页面视图控制器界面时,可以一次提供一个内容视图控制器(或一次提供两个,具体取决于脊椎位置和双面状态),也可以根据需要使用数据源提供内容视图控制器。一次提供一个内容视图控制器时,可以使用
setViewControllers(uquot:direction:animated:completion:)
方法设置当前的内容视图控制器要支持基于手势的导航,必须使用数据源对象提供视图控制器。


简单化的方法。。。在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

}

要从子视图控制器访问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的引用。我使用一个名为OrderViewController的数组来创建页面。我的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)
    }
现在,在子视图控制器中,您可以访问SetViewController。例如,如果我想在child1ViewController中调用SetViewController,我已经创建了一个名为AccessSetViewController()的func,在这里我可以访问SetViewController:

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

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

另一方面,不管上面的其他答案怎么说,您可以将dataSource设置为您喜欢的任何值。有时,我会将数据源设置为nil,以防止用户在执行某项操作之前从屏幕上滑动,然后再将数据源添加回屏幕,以允许他们继续滑动。

是的,我已经了解到了这一点。问题是,我不知道如何从我的子ViewController调用“SetViewController”。无论如何,感谢您的回复。如果您使用
goBack
/
goForward
等方法创建一个代理协议,并为您的子VCs添加一个弱属性,那就更好了。之后,让你的父母成为你孩子的VC的代理人。在这种情况下,您不需要直接从孩子们那里调用
setViewControllers
,他们对Page VCI一无所知,我会试试看!也许它能起作用,如果它能起作用,你的生活会更安全!谢谢你的回答。但代码中的“pageViewController”是什么?您正在创建子控制器时使用它。我尝试了您的解决方案,似乎一切都正常!到目前为止,最好的答案在网上找到!但是,我还有一个问题:假设我有3个子视图控制器,每个都嵌入到自己的导航控制器中。那么如何“创建子控制器”?仅使用导航控制器-Storyboard-ID引用它们不起作用。我需要换些别的东西吗?致以最良好的问候,非常感谢!如果我理解正确的话,你有一个PageViewController和三个孩子,但是每个孩子都有自己的导航控制器,对吗?您不需要引用导航控制器来创建子项。您只需要给孩子一个标识符并从中实例化,孩子就会知道自己有一个导航控制器。对于标识符为“child”但嵌入导航控制器中的子级,您可以这样做:让childVC=UIStoryboard(名称:“Main”,bundle:nil)。实例化eViewController(标识符为:“child”)为!ChildViewControllerI我今天尝试了你的建议,但无法正常运行。应用程序因信号1 Sigabrt或奇怪的解包裹错误而崩溃。。你能给我举个有效的例子吗?我会非常感激的。很抱歉我一直在问这些问题,但我对Swift还是相当陌生,仍然在努力学习!我很乐意帮忙,但也许是我不明白你想要实现什么。我认为最好是你们把这个问题放在堆栈上,我或任何人都可以试着回答。一些提示:如果可能的话,添加一个图表,添加您已经尝试过但不起作用的代码,在堆栈上提到任何对您不起作用的解决方案。