【问题标题】:Got nil for delegate at ViewController included in UIPageViewController在 UIPageViewController 中包含的 ViewController 的委托获得 nil
【发布时间】:2019-12-22 18:19:52
【问题描述】:

我有一个UIPageViewController 和几个ViewControllers。我想使用委托协议从ViewControllerUIPageViewController 中执行一个功能。但是在delegate 中获取nil。谁能确定我做错了什么?

PageViewController.swift

import UIKit

class PageViewController: UIPageViewController, UIPageViewControllerDelegate, UIPageViewControllerDataSource, Storyboarded {


    weak var coordinator: MainCoordinator?

    lazy var orderedViewControllers: [UIViewController] = {
        return [self.newInstanceVC(viewController: "FirstLoadViewController"), self.newInstanceVC(viewController: "FirstLoad2ViewController")]
    }()

    var pageControl = UIPageControl()

    override func viewDidLoad() {
        super.viewDidLoad()

        let storyboardVC = newInstanceVC(viewController: "FirstLoad2ViewController") as? FirstLoad2ViewController
        storyboardVC?.delegate = self

        self.dataSource = self
        if let firstViewController = orderedViewControllers.first {
            setViewControllers([firstViewController], direction: .forward, animated: true, completion: nil)
        }

        self.delegate = self
        configurePageControl()
    }


    func configurePageControl() {
        pageControl = UIPageControl(frame: CGRect(x: 0, y: UIScreen.main.bounds.maxY - 50, width: UIScreen.main.bounds.width, height: 50))
        pageControl.numberOfPages = orderedViewControllers.count
        pageControl.currentPage = 0
        //pageControl.tintColor = .red
        pageControl.pageIndicatorTintColor = .systemGray5
        pageControl.currentPageIndicatorTintColor = .systemGray
        self.view.addSubview(pageControl)
    }



        //return view controller by string identifier
    func newInstanceVC(viewController: String) -> UIViewController {
        return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: viewController)
    }


//MARK: - Setup page controllers

        // view controller that appears on swiping to the -> (left)
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

        guard let viewControllerIndex = orderedViewControllers.firstIndex(of: viewController) else {
            return nil
        }

        let previousIndex = viewControllerIndex - 1

        guard previousIndex >= 0 else {
            //return view controller from the end if it is last index from the left side (infinit scroll)
            //return orderedViewControllers.last
            return nil
        }

        guard orderedViewControllers.count >= previousIndex else {
            return nil
        }


        return orderedViewControllers[previousIndex]
    }

        // view controller that appears on swiping to the <- (right)
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

        guard let viewControllerIndex = orderedViewControllers.firstIndex(of: viewController) else {
            return nil
        }

        let nextIndex = viewControllerIndex + 1

        guard orderedViewControllers.count != nextIndex else {
            //return view controller from the begining if it is last index from the right side (infinit scroll)
            //return orderedViewControllers.first
            return nil
        }

        guard orderedViewControllers.count > nextIndex else {
            return nil
        }

        return orderedViewControllers[nextIndex]
    }

    func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
            //switch the bullet of the page
        let pageContentVievController = pageViewController.viewControllers![0]
        self.pageControl.currentPage = orderedViewControllers.firstIndex(of: pageContentVievController)!
    }

}


extension PageViewController: PageViewDelegate {
    func handleButtonTap() {
        coordinator?.goToMainFromPresentation()
    }


}

OneOfTheViewControllers.swift

import UIKit


protocol PageViewDelegate: class {
    func handleButtonTap()
}





class FirstLoad2ViewController: UIViewController, Storyboarded {


    weak var coordinator: MainCoordinator?
    weak var child: ChildCoordinator?

    weak var delegate: PageViewDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()



    }

    @IBAction func toMainScreenTap(_ sender: Any) {
        delegate!.handleButtonTap() //got nil for delegate here
    }

}

【问题讨论】:

    标签: ios swift delegates viewcontroller uipageviewcontroller


    【解决方案1】:

    问题很简单,它隐藏在你的viewDidLoad()方法里面PageViewController

    ...
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        let storyboardVC = newInstanceVC(viewController: "FirstLoad2ViewController") as? FirstLoad2ViewController
        storyboardVC?.delegate = self
    
           ...
    }
    /// (storyboardVC) --- will be destroyed when out of viewDidLoad() scope.
    

    那么,为什么你得到你的storyboardVC?.delegate = self nil?因为您在 viewDidLoad() 方法中创建了 storyboardVC 属性,并且没有任何东西保留对它的引用。所以,最后 viewDidLoad() 方法它只是取消初始化以及它的 PageViewDelegate delegate

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    相关资源
    最近更新 更多