【问题标题】:How do you pass data from a ViewController to a PageViewController containing separate ViewControllers which will then use this data?你如何将数据从 ViewController 传递到包含单独 ViewController 的 PageViewController,然后这些 ViewController 将使用这些数据?
【发布时间】:2015-06-15 17:14:19
【问题描述】:

我基本上有一个根 ViewController,我想将它传递到通过 PageViewController 连接的 ViewControllers 集合(所有不同的类本身)。

目前,我在根 ViewController 中设置了一个 prepareforsegue 来传递数据。然后我在 PageViewController 中声明了变量,并试图弄清楚如何将数据传递到 ViewControllers。

我目前只是在做一个简单的 Hello World 测试,所以我的代码有点简单。这是我的 RootViewController,我已将其传递到 PageViewController(并因此传递到连接到 PageViewController 的后续 VC):

class RootViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    var hello: String! = "Hello World!"
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if (segue.identifier == "testSegue"){

            var svc = segue.destinationViewController as! PageViewController;

            svc.datapassed = self.hello

        }
    }

我的 PageView 控制器有点复杂。我正在使用情节提要 ID 方法,因为我希望 pageviewcontroller 显示不同类的视图控制器,而不是显示一个视图控制器模板和不同图像内容的大量教程......

    class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

        var datapassed: String!

        var index = 0
        var identifiers: NSArray = ["FirstNavigationController", "SecondNavigationController"]

        override func viewDidLoad() {
            super.viewDidLoad()
            setupPageControl()
            self.dataSource = self
            self.delegate = self

            let startingViewController = self.viewControllerAtIndex(self.index)
            let viewControllers: NSArray = [startingViewController]
            self.setViewControllers(viewControllers as [AnyObject], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)

            // Do any additional setup after loading the view.
        }

        func viewControllerAtIndex(index: Int) -> UIViewController! {
            if index == 0 {

                return self.storyboard!.instantiateViewControllerWithIdentifier("FirstNavigationController") as! UIViewController

            }
            if index == 1 {

                return self.storyboard!.instantiateViewControllerWithIdentifier("SecondNavigationController") as! UIViewController
            }

            return nil
        }

        func pageViewController(pageViewController: UIPageViewController!, viewControllerAfterViewController viewController: UIViewController!) -> UIViewController! {

            let identifier = viewController.restorationIdentifier
            let index = self.identifiers.indexOfObject(identifier!)
            if index == identifiers.count - 1 {

                return nil
            }

            self.index = self.index + 1
            return self.viewControllerAtIndex(self.index)

        }

        func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {

            let identifier = viewController.restorationIdentifier
            let index = self.identifiers.indexOfObject(identifier!)
            if index == 0 {

                return nil
            }
            self.index = self.index - 1
            return self.viewControllerAtIndex(self.index)

        }

        private func setupPageControl() {
            let appearance = UIPageControl.appearance()
            appearance.pageIndicatorTintColor = UIColor.grayColor()
            appearance.currentPageIndicatorTintColor = UIColor.whiteColor()

        }

        func presentationCountForPageViewController(pageViewController: UIPageViewController!) -> Int {
            return self.identifiers.count
        }

        func presentationIndexForPageViewController(pageViewController: UIPageViewController!) -> Int {
            return 0
        }

    }

最后,我只是想让第一个 ViewController 连接到 pageviewcontroller 以显示来自传递的变量 datapassed 的文本。

    class FirstViewController: UIViewController {

        @IBOutlet weak var helloLabel: UILabel!
        override func viewDidLoad() {
            super.viewDidLoad()
            helloLabel.text = datapassed
            // Do any additional setup after loading the view.
        }
    }

编辑: 可能的解决方案和最终代码:

    class RootViewController: UIViewController {

        override func viewDidLoad() {
            super.viewDidLoad()

        }

        var carinfos: String! = "Hello World"
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
            if let svc = segue.destinationViewController as? PageViewController
                where segue.identifier == "testSegue" {
                    svc.dataPassed = self.carinfos
            }
        }
    }

class PageViewController: UIPageViewController, UIPageViewControllerDataSource, UIPageViewControllerDelegate {

    var dataPassed: String? {
        didSet {
            self.updateCurrentViewController()
        }
    }

    var index = 0
    var identifiers: NSArray = ["FirstNavigationController", "SecondNavigationController"]


    override func viewDidLoad() {
        super.viewDidLoad()
        self.dataSource = self
        self.delegate = self

        let startingViewController = self.viewControllerAtIndex(self.index)
        let viewControllers: NSArray = [startingViewController]
        self.setViewControllers(viewControllers as [AnyObject], direction: UIPageViewControllerNavigationDirection.Forward, animated: false, completion: nil)

    }

    func updateCurrentViewController() {

        if let firstViewController = self.viewControllerAtIndex(self.index) as? FirstViewController, let data = self.dataPassed {
            firstViewController.dataPassed = data
        }
    }


    func pageViewController(pageViewController: UIPageViewController!, viewControllerAfterViewController viewController: UIViewController!) -> UIViewController! {

        let identifier = viewController.restorationIdentifier
        let index = self.identifiers.indexOfObject(identifier!)
        if index == identifiers.count - 1 {

            return nil
        }
        self.index = self.index + 1
        return self.viewControllerAtIndex(self.index)

    }

    func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {

        let identifier = viewController.restorationIdentifier
        let index = self.identifiers.indexOfObject(identifier!)

        if index == 0 {

            return nil
        }

        self.index = self.index - 1
        let viewController = self.viewControllerAtIndex(self.index)
        self.updateCurrentViewController()

        return viewController
    }


    func viewControllerAtIndex(index: Int) -> UIViewController! {
        if index == 0 {
            return self.storyboard!.instantiateViewControllerWithIdentifier("FirstNavigationController") as! UIViewController
        }
        if index == 1 {
            return self.storyboard!.instantiateViewControllerWithIdentifier("SecondNavigationController") as! UIViewController
        }
        return nil
    }

    func presentationCountForPageViewController(pageViewController: UIPageViewController!) -> Int {
        return self.identifiers.count
    }

    func presentationIndexForPageViewController(pageViewController: UIPageViewController!) -> Int {
        return 0
    }


}

class FirstViewController: UIViewController {
    var dataPassed: String?

    @IBOutlet weak var firstLabelTest: UILabel!
    @IBOutlet weak var firstLabel: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()
        println(dataPassed)
        firstLabel.text = "Hello, this is First"
        self.populateData()
    }

    func populateData() {
        if let data = self.dataPassed {
            self.firstLabelTest.text = self.dataPassed
        }
    }

}

【问题讨论】:

    标签: ios xcode swift uiviewcontroller uipageviewcontroller


    【解决方案1】:

    您可以简单地将其传递给视图控制器结构以使其正常工作,尽管这并不是一个深思熟虑的设计。为此,首先,确保您使用if let 绑定和有条件的向下转换 (as?) 正确地转换了 destinationViewController。您还可以使用where 子句将比较与segue 的identifier 结合起来。然后,您将拥有设置数据的对象。

    FirstViewController 中,使用属性观察器在设置dataPassed 变量时更新标签,并在viewDidLoad 上更新它。

    此外,您的 hello 属性不应是隐式展开的类型,因此您可以从声明中删除 !

    class FirstViewController : UIViewController {
    
        @IBOutlet weak var helloLabel: UILabel!
    
        var dataPassed: String?
    
        override func viewDidLoad() {
            super.viewDidLoad()
            self.populateData()
        }
    
        func populateData() {
            if let data = self.dataPassed {
                self.helloLabel.text = self.dataPassed
            }
        }
    
    }
    
    class PageViewController : UIPageViewController {
    
        var index = 0
        var identifiers: NSArray = ["FirstNavigationController", "SecondNavigationController"]
    
        var dataPassed: String? {
            didSet {
                self.updateCurrentViewController()
            }
        }
    
        func pageViewController(pageViewController: UIPageViewController!, viewControllerBeforeViewController viewController: UIViewController!) -> UIViewController! {
    
            let identifier = viewController.restorationIdentifier
            let index = self.identifiers.indexOfObject(identifier!)
            if index == 0 {
    
                return nil
            }
            self.index = self.index - 1
            let viewController = self.viewControllerAtIndex(self.index)
    
            self.updateCurrentViewController()
    
            return viewController
        }
    
        func updateCurrentViewController() {
    
            if let firstViewController = self.viewControllerAtIndex(self.index) as? FirstViewController, let data = self.dataPassed {
                firstViewController.dataPassed = data
            }
        }
    
        func viewControllerAtIndex(index: Int) -> UIViewController! {
            // Create your VC as in the project template
            return nil
        }
    }
    
    class RootViewController : UIViewController {
    
        var hello: String = "Hello World!"
    
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
            super.prepareForSegue( segue, sender: sender )
            if let svc = segue.destinationViewController as? PageViewController
                where segue.identifier == "testSegue" {
                    svc.dataPassed = self.hello
            }
        }
    }
    

    【讨论】:

    • 感谢您的回复。我想知道当您在 FirstViewController 中声明 dataPassed 时 didset 方法做了什么。此外,该行实际上是如何从 RootViewController 提取数据传递的,因为在情节提要上,segue 实际上是从 RootView 到 PageViewController?
    • 对不起,我误解了你的结构,答案已更新。
    • 啊。我觉得我很接近。我摆弄了几个小时的代码,但我无法让数据通过。该项目构建没有任何错误。但是,只是 dataPassed 在 FirstViewController 中不断返回 nil。我已经从上面更新了我的代码,我很确定我没有犯错,但不太确定。
    【解决方案2】:

    根据您的应用程序的需求和其他结构,您还可以使用响应者链向层次结构中的任何视图控制器提供数据。

    那么就这么简单:

    class FirstViewController : UIViewController {
    
        @IBOutlet weak var helloLabel: UILabel!
    
        var dataPassed: String? {
            didSet {
                if let data = self.dataPassed {
                    self.helloLabel.text = data
                }
            }
        }
    
        override func viewWillAppear(animated: Bool) {
            super.viewWillAppear(animated)
    
            if let dataSource = self.nextResponder()?.targetForAction( "hello", withSender: self ) as? RootViewController {
                self.dataPassed = dataSource.hello
            }
        }
    
    }
    
    class RootViewController : UIViewController {
    
        var hello: String = "Hello World!"
    
    }
    

    【讨论】:

      【解决方案3】:

      swift3 你可以这样做 在您嵌入 pageviewcontroller 的主视图中,您可以使用带有标识符的 segue

      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
              if segue.identifier=="challengepostssegue"{
               let destination=segue.destination as! PageMainController
                  destination.challengeId=challengId
              }
          }
      

      在PageMainController中声明一个变量可选类型

      var challengeId:String?
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-08
        • 2021-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多