如何从父控制器更改嵌入式控制器中的 UIColor?

How to change UIColor in Embeded controller from parent controller?

我是 Swift 的新手,目前对 代表 很感兴趣。 我需要从父控制器中的按钮更改嵌入式控制器 UIColor。

这是我试过的方法

1) 我用 func 和 UIColor 创建了一个委托协议作为 arumetn 2) 在ParentVC(ThirdViewController)

中添加一个实例

父级中的代码VC

    import UIKit

protocol TVCDelegate: class {
    func setColor(color: UIColor)
}

class ThirdViewController: UIViewController {

    weak var delegate: TVCDelegate?


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? AdditionalThirdViewController {
            vc.setColor(color: UIColor.red) }}

    @IBAction func redButton(_ sender: Any?) {
        I need this button to change color in **Embedded VC** }

    override func viewDidLoad() {
        super.viewDidLoad() }


    }


}

extension ThirdViewController: TVCDelegate {
    func setColor(color: UIColor) {
        view.backgroundColor = color
    } }

嵌入式代码vc

import UIKit

class AdditionalThirdViewController: UIViewController {


    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let vc = segue.destination as? ThirdViewController {
            vc.delegate = self } }

    @IBAction func redButton(_ sender: Any) {
    }

    override func viewDidLoad() {
        super.viewDidLoad()

最后我需要两个控制器都有三个按钮,每个按钮都可以在其他控制器中改变颜色。

我怎样才能做到这一点? 还有你有什么建议可以阅读关于假人代表的内容吗?

我强烈建议您详细阅读本文并了解委托的工作原理和相关数据

https://medium.com/@jamesrochabrun/implementing-delegates-in-swift-step-by-step-d3211cbac3ef

在您的情况下,您必须像这样在 ThirdViewController 中点击按钮时调用委托方法。

@IBAction func redButton(_ sender: Any?) {
   delegate?.setColor(UIColor.red)
}

以上代码将调用值为 red 的委托方法。现在你需要在 EmbededViewController 中捕获这个值并且需要像这样实现 TVCDelegate

extension AdditionalThirdViewController: TVCDelegate {
    func setColor(color: UIColor) {
    //Set Color sent by ThirdViewController
    }
}

同样,您需要了解委托基础知识。

另外删除您在 ThirdViewController 中编写的这段代码

extension ThirdViewController: TVCDelegate {
    func setColor(color: UIColor) {
        view.backgroundColor = color
    } }

Class 声明委托不能实现相同的委托。

您需要注册通知并调用它。让我向您解释一下如何在第一个 viewcontroller 添加此代码的按钮单击时首先执行此操作:

NotificationCenter.default.post(name: NSNotification.Name(rawValue: "changeColor"), object: nil, userInfo: nil)

添加该代码后转到第三个视图控制器并在视图中添加此代码:

 NotificationCenter.default.addObserver(self, selector: #selector(YOURVIEWCONTROLLERNAME.changeColor(notification:)), name: Notification.Name(rawValue: "changeColor"), object: nil) 

然后在第三个中添加此方法viewcontroller

 @objc func changeColor(notification: NSNotification)
    {
        self.view.backgroundColor = .red
    }

你现在已经准备好了。

尝试提供更多说明...

协议/委托设计模式允许我们"delegate" 为另一个class/对象工作。

一个非常常用的案例 - 人们甚至没有意识到他们正在使用它 - 是 table 视图。 table 视图本身检测用户何时点击一行,然后告诉它的 delegate 刚刚发生的事情。那时,table 视图不知道应该根据行选择采取什么操作......它只是告诉它的委托(table 视图控制器):

"Hey! The user selected on of my rows!"

控制器通过实施符合该协议:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    // do something because a row was selected
}

在此实现中,我们知道 发送了该消息 (tableView),并且我们知道选择了哪一行(indexPath)。 table 视图本身不需要知道行的内容或接下来应该发生什么......它 delegates 该任务交给控制器。

在你的例子中,你想要将视图控制器加载到容器视图中,并让该控制器中的按钮告诉它的委托(父控制器)"a button was tapped" 并让父控制器决定做什么-- 比如改变它的背景颜色。

对于 parent 视图控制器中的按钮,您只需设置容器 VC 视图的 .backgroundColor 属性,或者,可选地,调用该控制器中的函数。

我在几年前整理了一个简单的、非常相似的示例,并对其进行了更新以更好地反映您正在尝试做的事情。您可以在这里找到它:https://github.com/DonMag/ContainerDelegate

看起来像这样:

点击青色或橙色按钮(在主控制器中)将更改容器视图中 VC 的背景。

点击容器视图中的红色或绿色按钮将告诉它的 delegate:

"Hey! A color button was tapped!"

委托函数(在主控制器中)将更改大标签的背景颜色。