如何使用委托将数据从UIPageViewController传递给子ViewController

时间:2017-05-04 14:43:58

标签: ios swift delegates protocols uipageviewcontroller

我想将UIPageViewController的数据传递给其子ViewControllers之一。 我有一个像这样的协议集:

protocol Delegate : class{
    func protocolMethod(count:Int)
}

UIPageViewController

class PageVC : UIPageViewController{
    var delegate : Delegate?
    var count : Int = 1

    func classMethod(){
        self.displayPageForIndex(5) //this controlls the tranistion to the child ViewController 
        self.delegate?.protocolMethod(count : self.count) 
    }
}

符合要求的孩子ViewController

class ChildVC : UIViewController , Delegate{

    func protocolMethod(count : Int){
        print(count)
    }

    override func viewDidLoad() { 
        super.viewDidLoad()
        let pvc = PageVC()
        pvc.delegate = self
    }
}

我在viewDidLoad中所做的是我尝试过的最简单的解决方案,但仍然无法找到如何让PageViewController知道的答案孩子ViewController是协议方法的接收者。 如果有人可以帮助我在不使用prepareForSegue(因为没有segues)的情况下完成它,那将非常感激。

2 个答案:

答案 0 :(得分:1)

问题在于这一行:

    let pvc = PageVC()

这使得新的,独立的 PageVC。这不是你想要的。您想要引用其父级的现有的,实际的 PageVC。该引用是self.parent(尽管不是,可能在viewDidLoad中,这是相当早的,可能无法保证我们还是孩子)。

答案 1 :(得分:0)

如果您的子视图控制器知道它始终位于UIPageViewController的上下文中,那么您可以使用视图控制器中的父/子链接来允许这些控制器相互发现并交换数据。在这些情况下特别有用的是UIViewController类引用的响应包含事件部分中的方法。

如果您想使用协议,那么我将在页面视图控制器上定义协议,并在创建时将该协议传递给子视图控制器。所以:

protocol MyDataSourceProtocol {
  func gimmeSomeData() -> Data
}

// The UIPageViewController implements MyDataSourceProtocol because
// he's going to provide information to his children.
class PageVC : UIPageViewController, MyDataSourceProtocol {
  func gimmeSomeData() -> Data {
      ...
  }

  func makeChildViewControllers() -> ChildViewControllers {
      return childControllerElements.map {
        element : ChildControllerElement in

        // pass self to let the child view controller know I'll be his
        // source
        return ChildViewController(self)
      }
  }
}

然后确保您的孩子视图控制器知道要获取内容

class ChildViewController : UIViewController {
  let dataSource : MyDataSourceProtocol
  init(dataSource : MyDataSourceProtocol) {
    self.dataSource = dataSource
  }
}

最后一些关于风格的评论:

您需要小心使用术语“委托”,因为它在Cocoa API的上下文中具有非常特定的含义,并且您在此处的使用与该含义不匹配。同样用小写字母(childVC)命名一个类的风格很差。