委派从 child 视图到主视图的更改

Delegate change from child view to main view

我有带 mainView 和 ChildView 的 UIViewController。 我想在 mainView 中从 ChildView

更改标签

Child 我加

let to = ChildView()
self.addChild(to)
self.mainView.addSubview(to.view)
self.mainViewConstraint.constant = to.view.frame.height
to.view.frame = self.mainView.bounds
to.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

mainView - 它的视图,其中显示 childView

我试着用委托来做这个 在 Child视图中:

protocol UserDelegate {
    func changeName(name: String)
}

class ChildView: UIViewController {

     var userDelegate: UserDelegate?

    @IBAction func changeNameBtn(_ sender: UIButton) {
        self.userDelegate?.changeName(name: "TestChanges")
    }
}

在主视图中:

class MainView: UIViewController, UserDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        let ChildView = ChildView()
        ChildView.userDelegate = self
    }

    func changeName(name: String) {
        self.helloLabel.text = "Hello \(name)!"
    }
}

问题是您提供了 ChildView 的一个实例并在 ChildView 的另一个实例上设置了委托。因此屏幕上显示的子视图与调用委托的子视图不同。添加 ChildView:

时设置委托
let to = ChildView()
self.addChild(to)
self.mainView.addSubview(to.view)
self.mainViewConstraint.constant = to.view.frame.height

// set the delegate here
to.userDelegate = self.mainView

to.view.frame = self.mainView.bounds
to.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]

此外,为防止循环保留,请使用 weak 对委托的引用:

protocol UserDelegate: AnyObject {
    func changeName(name: String)
}

class ChildView: UIViewController {

    weak var userDelegate: UserDelegate?

    @IBAction func changeNameBtn(_ sender: UIButton) {
        self.userDelegate?.changeName(name: "TestChanges")
    }
}

最后,您可以从主视图中删除 viewDidLoad 实现:

class MainView: UIViewController, UserDelegate {
    // this should be enough
    func changeName(name: String) {
        self.helloLabel.text = "Hello \(name)!"
    }
}