尝试使用闭包在ViewController之间传递数据时出现什么错误?

时间:2019-12-21 08:33:05

标签: ios swift

我的主View Controller中有一个嵌入式UITabbarController。有2个子VC:viewControllerONE和viewControllerTWO。

viewControllerONE显示一个标签,该标签显示用户的当前分数,viewControllerTWO显示一个按钮,按下该按钮应在viewControllerONE上显示一个错误窗口。  (为简单起见,用户必须使用标签栏手动导航至viewControllerONE才能看到错误,即,按下viewControllerTWO上的按钮不会带您进入viewControllerONE,然后显示errorWindow。)

错误窗口是一个简单的UIView类。

从SO中,我了解到,快速传递数据的最佳方法不是委托而是闭包,因为前者更多是目标C设计,因此我使用闭包在视图控制器之间传递数据。

这是我的viewControllerONE代码:

class ViewControllerONE: UIViewController {

    var score = 10

    lazy var scoreLabel: UILabel = {
        let label = UILabel()
        label.text = String(score)
        label.font = .systemFont(ofSize: 80)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.textAlignment = .center
        return label
    }()


    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        view.addSubview(scoreLabel)

         let VC = ViewControllerTWO()

    VC.callback = { [weak self ] in
        let error = errorView()
        self?.view.addSubview(error)
        }


        NSLayoutConstraint.activate([
        scoreLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        scoreLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor)
    ])

  }

}

这是我的viewControllerTWO代码:

class ViewControllerTWO: UIViewController {

    var callback: (() -> Void)?

    let buttonTwo: UIButton = {
             let button = UIButton()
             button.setTitle("HIT THIS BUTTON!", for: .normal)
             button.backgroundColor = .systemBlue
             button.translatesAutoresizingMaskIntoConstraints = false
             button.addTarget(self, action: #selector(buttonTwoPressed), for: .touchUpInside)
             button.layer.cornerRadius = 8
             return button
         }()

         @objc func buttonTwoPressed() {
             print("PRESSEDDDD")
            callback?()
         }


    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        view.addSubview(buttonTwo)

                 NSLayoutConstraint.activate([
                 buttonTwo.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                 buttonTwo.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        ])
    }

}

这是错误视图:

class ErrorView: UIView {


    fileprivate let dismissButton: UIButton = {
        let button = UIButton()
        button.setTitle("DISMISS!!!!", for: .normal)
        button.backgroundColor = .systemBlue
        button.translatesAutoresizingMaskIntoConstraints = false
        button.addTarget(self, action: #selector(dismissButtonPressed), for: .touchUpInside)
        button.layer.cornerRadius = 12
        return button
    }()

    @objc func dismissButtonPressed() {
    self.errorGoAway()
    }


    fileprivate let errorViewBox: UIView = {
        let v = UIView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.backgroundColor = .white
        v.layer.cornerRadius = 24
        return v
    }()

    @objc fileprivate func errorGoAway() {
            self.alpha = 0
    }

    @objc fileprivate func errorShow() {
        self.alpha = 1
    }

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(errorGoAway)))
        self.backgroundColor = UIColor.gray
        self.backgroundColor?.withAlphaComponent(0.8)
        self.frame = UIScreen.main.bounds
        self.addSubview(errorViewBox)

        errorViewBox.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        errorViewBox.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        errorViewBox.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.7).isActive = true
        errorViewBox.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 0.45).isActive = true

        errorViewBox.addSubview(dismissButton)
        dismissButton.leadingAnchor.constraint(equalTo: errorViewBox.leadingAnchor).isActive = true
        dismissButton.trailingAnchor.constraint(equalTo: errorViewBox.trailingAnchor).isActive = true
        dismissButton.centerYAnchor.constraint(equalTo: errorViewBox.centerYAnchor).isActive = true
        dismissButton.heightAnchor.constraint(equalTo: errorViewBox.heightAnchor, multiplier: 0.15).isActive = true

        errorShow()
    }

1 个答案:

答案 0 :(得分:1)

您需要从tabBarController获取控制器,而不是创建新实例:

class ViewControllerONE: UIViewController {

var score = 10

lazy var scoreLabel: UILabel = {
    let label = UILabel()
    label.text = String(score)
    label.font = .systemFont(ofSize: 80)
    label.translatesAutoresizingMaskIntoConstraints = false
    label.textAlignment = .center
    label.textColor = .blue
    return label
}()


override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white

    view.addSubview(scoreLabel)

    var VC: ViewControllerTWO?

    let arrayOfVC = self.tabBarController?.viewControllers ?? []

    for item in arrayOfVC {
        if let secondVC = item as? ViewControllerTWO {
            VC = secondVC
            break
        }
    }

    VC?.callback = { [weak self ] in
        let error = ErrorView()
        self?.view.addSubview(error)
    }

    NSLayoutConstraint.activate([
        scoreLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor),
        scoreLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor)
    ])

  }
}