Получил ноль для делегата в ViewController, включенного в UIPageViewController - PullRequest
0 голосов
/ 22 декабря 2019

У меня есть UIPageViewController и несколько ViewControllers в нем. И я хочу выполнить функцию в UIPageViewController из ViewController с использованием протокола делегата. Но получите nil в delegate. Кто-нибудь может определить, что я делаю неправильно?

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
    }

}

1 Ответ

0 голосов
/ 23 декабря 2019

Проблема проста, она прячется в вашем 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 ноль ? Потому что вы создали storyboardVC свойство внутри viewDidLoad() метода, и ничто не хранит ссылку на него. Итак, в конце метода viewDidLoad() он просто деинициализируется так же, как и PageViewDelegate delegate

...