子 ViewController 未收到来自父 PageViewController 的委托调用

问题描述

我正在尝试通过委托调用从父 PageViewController 向子 ViewController 发送一些数据。但是,目前,这不起作用。我的视图设置如下:

  • ViewController(其中包含一个地图视图,其中的数据需要传递给ParentPageVC)
    • ParentPageViewController(然后需要将接收到的数据传递给 ChildTwoVC)
      • ChildOneViewController
      • ChildTwoViewController(显示从父级接收到的数据)

有趣的是,我可以在父 PageViewController 内的子级之间发送数据。我也可以将数据从初始 ViewController 发送到 ParentPageViewController 就好了。我只是无法将数据从父级发送到子级。

这是我的父 PageViewController:

protocol ParentPageViewDelegate: class {
    func viewNeedsdismiss()
}

class ParentPageViewController: UIPageViewController,UIPageViewControllerDelegate,UIPageViewControllerDataSource,ParentPageViewDelegate,MyMapDataViewDelegate {
    
    lazy var childViewControllers = [UIViewController]()
    weak var childTwoViewDelegate: ChildTwoViewDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()

        self.dataSource = self
        self.delegate = self
        
        let childOneViewController = storyboard?.instantiateViewController(withIdentifier: "ChildOneViewController") as! ChildOneViewController
        let childTwoViewController = storyboard?.instantiateViewController(withIdentifier: "ChildTwoViewController") as! ChildTwoViewController
        
        childOneViewController.childOneDelegate = childTwoViewController
        childTwoViewController.parentPageViewDelegate = self
        self.childTwoViewDelegate = childTwoViewController
        workoutViewControllers.append(childOneViewController)
        workoutViewControllers.append(childTwoViewController)
        
        if let firstViewController = workoutViewControllers.last {
            setViewControllers([firstViewController],direction: .forward,animated: true,completion: nil)
        }
        
        let pageControl = UIPageControl.appearance(whenContainedInInstancesOf: [StartWorkoutPageViewController.self])
        pageControl.currentPageIndicatorTintColor = .orange
        pageControl.pageIndicatorTintColor = .gray
    }
    
    // MARK: Delegates
    // ParentPageView Delegate
    func viewNeedsdismiss() {
        // Works fine
        print("Willdismiss")
    }
    
    // MyMapDataView Delegate
    func updateStats(distance: String,rawdistance: Double,speedPace: String) {
        print("Method Was Called") // Yes,the method is called.
        // However nothing happens in the below line... it doesn't call 'childTwoViewDelegate'
        childTwoViewDelegate?.updateStats(distance: distance,rawdistance: rawdistance,speedPace: speedPace)
    }
    
    // MARK: PageView DataSource
    func pageViewController(_ pageViewController: UIPageViewController,viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = childViewControllers.firstIndex(of: viewController) else {
            return nil
        }
        
        let prevIoUsIndex = viewControllerIndex - 1
        
        guard prevIoUsIndex >= 0 else {
            return childViewControllers.last
        }
        
        guard childViewControllers.count > prevIoUsIndex else {
            return nil
        }
        
        return childViewControllers[prevIoUsIndex]
    }
    
    func pageViewController(_ pageViewController: UIPageViewController,viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = childViewControllers.firstIndex(of: viewController) else {
            return nil
        }
        
        let nextIndex = viewControllerIndex + 1
        let childViewControllersCount = childViewControllers.count
        
        guard childViewControllersCount != nextIndex else {
            return workoutViewControllers.first
        }
        
        guard childViewControllersCount > nextIndex else {
            return nil
        }
        
        return childViewControllers[nextIndex]
    }
    
    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return childViewControllers.count
    }
    
    func presentationIndex(for pageViewController: UIPageViewController) -> Int {
        guard let firstViewController = viewControllers?.first,let firstViewControllerIndex = workoutViewControllers.firstIndex(of: firstViewController) else {
            return 0
        }
        
        return firstViewControllerIndex
    }
}

我的子视图控制器:


protocol ChildTwoViewDelegate: class {
    func updateStats(distance: String,speedPace: String)
}

class ChildTwoViewController: UIViewController,ChildTwoViewDelegate {

    weak var parentPageViewDelegate: ParentPageViewDelegate?

    @IBAction func closeButton(_sender: Any) {
        // Works fine
        parentPageViewDelegate?.viewNeedsdismiss()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    // MARK: Delegates
    // ChildTwoViewDelegate
    func updateStats(distance: String,speedPace: String) {
        // This method does not get called.
        print("Method Was Called in Child") 
    }
}

谢谢!

解决方法

我只是去掉了我无法使用的部分并在 Xcode 中运行它,它对我有用。我会发布功能部分,也许它会帮助您推断问题。我没有看到您的代码有任何明显错误。可能是故事板的问题。我不使用故事板,所以我无法对此发表评论。

protocol ParentPageViewDelegate: class {
    func viewNeedsDismiss()
}

class ParentPageViewController: UIViewController,ParentPageViewDelegate {
    
//    lazy var childViewControllers = [UIViewController]()
    weak var childTwoViewDelegate: ChildTwoViewDelegate?
    let childTwoViewController = ChildTwoViewController()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
//        let childOneViewController = storyboard?.instantiateViewController(withIdentifier: "ChildOneViewController") as! ChildOneViewController
//        let childTwoViewController = storyboard?.instantiateViewController(withIdentifier: "ChildTwoViewController") as! ChildTwoViewController
        
//        childOneViewController.childOneDelegate = childTwoViewController
        childTwoViewController.parentPageViewDelegate = self
        self.childTwoViewDelegate = childTwoViewController
        childTwoViewDelegate?.updateStats(distance: "test",rawDistance: 3.4,speedPace: "none")
//        workoutViewControllers.append(childOneViewController)
//        workoutViewControllers.append(childTwoViewController)
//
//        if let firstViewController = workoutViewControllers.last {
//            setViewControllers([firstViewController],direction: .forward,animated: true,completion: nil)
//        }
        
//        let pageControl = UIPageControl.appearance(whenContainedInInstancesOf: [StartWorkoutPageViewController.self])
//        pageControl.currentPageIndicatorTintColor = .orange
//        pageControl.pageIndicatorTintColor = .gray
    }
    
    // MARK: Delegates
    // ParentPageView Delegate
    func viewNeedsDismiss() {
        // Works fine
        print("WillDismiss")
    }
    
    // MyMapDataView Delegate
    func updateStats(distance: String,rawDistance: Double,speedPace: String) {
        print("Method Was Called") // Yes,the method is called.
        // However nothing happens in the below line... it doesn't call 'childTwoViewDelegate'
        childTwoViewDelegate?.updateStats(distance: distance,rawDistance: rawDistance,speedPace: speedPace)
    }
    
    // MARK: PageView DataSource
//    func pageViewController(_ pageViewController: UIPageViewController,viewControllerBefore viewController: UIViewController) -> UIViewController? {
//        guard let viewControllerIndex = childViewControllers.firstIndex(of: viewController) else {
//            return nil
//        }
//
//        let previousIndex = viewControllerIndex - 1
//
//        guard previousIndex >= 0 else {
//            return childViewControllers.last
//        }
//
//        guard childViewControllers.count > previousIndex else {
//            return nil
//        }
//
//        return childViewControllers[previousIndex]
//    }
//
//    func pageViewController(_ pageViewController: UIPageViewController,viewControllerAfter viewController: UIViewController) -> UIViewController? {
//        guard let viewControllerIndex = childViewControllers.firstIndex(of: viewController) else {
//            return nil
//        }
//
//        let nextIndex = viewControllerIndex + 1
//        let childViewControllersCount = childViewControllers.count
//
////        guard childViewControllersCount != nextIndex else {
////            return workoutViewControllers.first
////        }
//
//        guard childViewControllersCount > nextIndex else {
//            return nil
//        }
//
//        return childViewControllers[nextIndex]
//    }
    
//    func presentationCount(for pageViewController: UIPageViewController) -> Int {
//        return childViewControllers.count
//    }
    
//    func presentationIndex(for pageViewController: UIPageViewController) -> Int {
//        guard let firstViewController = viewControllers?.first,let firstViewControllerIndex = workoutViewControllers.firstIndex(of: firstViewController) else {
//            return 0
//        }
//
//        return firstViewControllerIndex
//    }
}


protocol ChildTwoViewDelegate: class {
    func updateStats(distance: String,speedPace: String)
}

class ChildTwoViewController: UIViewController,ChildTwoViewDelegate {

    weak var parentPageViewDelegate: ParentPageViewDelegate?

    @IBAction func closeButton(_sender: Any) {
        // Works fine
        parentPageViewDelegate?.viewNeedsDismiss()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    // MARK: Delegates
    // ChildTwoViewDelegate
    func updateStats(distance: String,speedPace: String) {
        // This method does not get called.
        print("Method Was Called in Child")
    }
}

如果这有帮助,请告诉我。