首页 > 解决方案 > 为什么我不能在不弄乱我的关闭代码的情况下向我的 UIPageViewController 添加多个(相同的)ViewController?

问题描述

我的应用程序的设置如下:

RootVC,它有一个计数器 UILabel

嵌入在 UIPageViewController 中的 subContainer VC,“FirstVC”,它占据了 RootVC 的下半部分。FirstVC 有一个按钮,按下它会将 RootVC 上的 UILabel 增加一个。

现在我使用闭包在 2 个 ViewController 之间进行通信,最初工作正常,但是当我尝试添加两个 ViewController(SecondVC 和 ThirdVC)时,它们都与 FirstVC 完全相同,并且每个都有一个按钮来做同样的事情(包括关闭回调),由于某种原因,这会引发错误,我无法理解

FirstVC(以及 SecondVC & ThirdVC)如下:

class FirstVC {
    var buttonCallback: () -> Void = { }

    @objc func buttonPressed(_ sender: UIButton) {
        buttonCallback()
    }
}

我的 RootVC:

class RootVC: UIViewController {

    var tappedCount: Int = 0 {
        didSet { 
            label.text = "\(tappedCount)"
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        let pageController = PageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)
        pageController.buttonCallback = { self.tappedCount += 1 }
    }
}

而我的 UIPageViewController 类如下:

class PageViewController: UIPageViewController {

var subViewControllers = [FirstSubVC(), SecondSubVC(), ThirdVC()] {
             didSet {
                 // just in case the controllers might change later on
                subViewControllers.forEach { $0.buttonCallback = buttonCallback } ////ERROR: Value of type 'UIViewController' has no member 'buttonCallback'////
             }
         }

  var buttonCallback: () -> Void = { } {
      didSet {
        subViewControllers.forEach { $0.buttonCallback = buttonCallback } ////ERROR: Value of type 'UIViewController' has no member 'buttonCallback'////
      }
  }

extension PageViewController: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return subViewControllers.count
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        let currentIndex:Int = subViewControllers.firstIndex(of: viewController as! FirstVC) ?? 0
        if currentIndex <= 0 {
            return nil
        }
        return subViewControllers[currentIndex-1]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        let currentIndex:Int = subViewControllers.firstIndex(of: viewController as! FirstVC) ?? 0
        if currentIndex >= subViewControllers.count-1 {
            return nil
        }
        return subViewControllers[currentIndex+1]
    }
}

我试图不在 UIPageViewController 扩展中将 viewController 转换为 FirstVC ,但这会产生另一个问题,我认为这不是解决这个问题的正确方法。

编辑

protocol CallableThing {
var buttonCallback: () -> Void = { } //ERROR Property in protocol must have explicit { get } or { get set } specifier
}

标签: swift

解决方案


您的代码无法正常工作。您必须通过属性识别控制器,使用该title属性或采用Identifiable协议

例如

class FirstVC : UIViewController {

    func viewDidLoad() {
        super.viewDidLoad()
        title = "First"
    }

    var buttonCallback: () -> Void = { }

    @objc func buttonPressed(_ sender: UIButton) {
        buttonCallback()
    }
}

extension PageViewController: UIPageViewControllerDelegate, UIPageViewControllerDataSource {
    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return subViewControllers.count
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let currentIndex = subViewControllers.firstIndex(where: {$0.title == viewController.title}), currentIndex > 0 else { return nil }
        return subViewControllers[currentIndex-1]
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let currentIndex = subViewControllers.firstIndex(where: {$0.title == viewController.title}), currentIndex <= subViewControllers.count-1 else { return nil }
        return subViewControllers[currentIndex+1]
    }
}

推荐阅读