Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
151 views
in Technique[技术] by (71.8m points)

ios - Child ViewController Not Receiving Delegate Calls from Parent PageViewController

I'm trying to send some data with a delegate call from a Parent PageViewController to a Child ViewController. However, at the moment, this doesn't work. I have my views set up like this:

  • ViewController (which contains a map view, in which data needs to be passed to the ParentPageVC)
    • ParentPageViewController (which then needs to pass the data received to ChildTwoVC)
      • ChildOneViewController
      • ChildTwoViewController (displays the data received from parent)

Interestingly, I can send data between the children inside the parent PageViewController. I can also send data from the initial ViewController to the ParentPageViewController just fine. I just cannot send the data from the Parent TO the Child.

Here's my Parent 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
    }
}

My Child ViewController:


protocol ChildTwoViewDelegate: class {
    func updateStats(distance: String, rawDistance: Double, 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, rawDistance: Double, speedPace: String) {
        // This method does not get called.
        print("Method Was Called in Child") 
    }
}

Thank you!

question from:https://stackoverflow.com/questions/65946997/child-viewcontroller-not-receiving-delegate-calls-from-parent-pageviewcontroller

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I just stripped the parts out that I couldn't use and ran it in Xcode and it worked for me. I'll post the functioning part and maybe it'll help you deduce the problem. I don't see anything conspicuously wrong with your code. It may be a problem with the storyboard. I don't use storyboards so I can't comment on that.

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, rawDistance: Double, 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, rawDistance: Double, speedPace: String) {
        // This method does not get called.
        print("Method Was Called in Child")
    }
}

Let me know if this helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...