【问题标题】:How to change UIColor in Embeded controller from parent controller?如何从父控制器更改嵌入式控制器中的颜色?
【发布时间】:2020-05-26 16:07:08
【问题描述】:

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

这是我尝试过的

1) 我创建了一个使用 func 和 UIColor 作为 arumetn 的委托协议 2)在Parent VC(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()

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

我怎样才能做到这一点? 另外,您是否有建议阅读有关傻瓜代表的内容?

【问题讨论】:

    标签: ios swift uiviewcontroller uicollectionview uicolor


    【解决方案1】:

    尝试提供更多说明...

    协议/委托设计模式允许我们将工作“委托”给另一个类/对象。

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

    “嘿!用户选择了我的行!”

    并且控制器符合通过实现该协议:

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

    在这个实现中,我们知道 正在发送该消息 (tableView),并且我们知道选择了哪一行 (indexPath)。表格视图本身不需要知道任何关于行的内容或接下来应该发生的事情......它该任务委托给控制器。 p>

    在您的情况下,您希望将视图控制器加载到容器视图中,并让该控制器中的按钮告诉其委托(父控制器)“按钮被点击”并让父控制器决定做什么 - - 比如改变它的背景颜色。

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

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

    看起来像这样:

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

    点击容器视图中的红色或绿色按钮将告诉其代表

    “嘿!点击了一个颜色按钮!”

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

    【讨论】:

    • 非常感谢,我明白了:)
    【解决方案2】:

    您需要注册通知并调用它。让我向您解释如何在第一个视图控制器的按钮单击时首先添加此代码:

    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) 
    

    然后在thirdviewcontroller中添加这个方法

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

    现在一切就绪。

    【讨论】:

      【解决方案3】:

      我强烈建议您详细阅读这篇文章并了解委托的工作原理和周围的数据

      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
          } }
      

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

      【讨论】:

      • 感谢您的回答和文章。我实现了建议的代码,但 redButton 不会改变屏幕颜色。我应该向 Embedded VC (AdditionalThirdViewController) 添加一些东西吗? Delegate 仅传递 UIColor 值,但不传递 Delegates 方法实现。我在嵌入式控制器的扩展中添加了“view.backgroundcolor = color”,但我认为我应该以某种方式调用它?
      猜你喜欢
      • 1970-01-01
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-06
      • 2020-01-20
      • 1970-01-01
      • 2019-08-18
      相关资源
      最近更新 更多