是否可以修改 Swift 4 中父 class 的子 class 的属性?

Is it possible to modify the properties of a subclass from a parent class in Swift 4?

也许是通过方法或闭包?

我为 superclass/parent 视图控制器创建了一个子class 视图控制器,并在该子class 视图控制器中放置了带有占位符文本的标签。

我想将标签的值设置为来自 superclass/parent 视图控制器的空白字符串,或者,具体来说,来自导致 subclass 视图控制器出现的 IBAction 函数。

这是代码,首先来自父 class,然后来自子class...

'''

  class ViewController: UIViewController {
            @IBAction func leavingView(){
                    self.EntryViewController.entryDateLabel.text = ""
                    self.EntryViewController.entryLabel.text = ""
                    self.dismiss(animated: true, completion: nil)
            }

''' 然后从 subclass... '''

  class EntryViewController: ViewController {

            @IBOutlet var entryDateLabel: UILabel!
            @IBOutlet var entryLabel: UILabel!
     }

'''

由于您的要求不是很清楚,我为您创建了一个演示,并在该演示中添加了 child ContainerViewController 到 parent ViewController 和parent 视图控制器您可以在单击 parent ViewControllerUIButton 时更改 UILabel 文本,代码将用于 ViewController

class ViewController: UIViewController {

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

    @IBAction func btnFromParentViewTapped(_ sender: Any) {

        //Here get the child of your parent view controller
        if let containerView = self.children[0] as? ContainerViewController {
            containerView.lblContainer.text = ""
        }
    }
}

ContainerViewController代码将是:

class ContainerViewController: UIViewController {

    @IBOutlet weak var lblContainer: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }
}

无需在此处添加太多内容,因为您是从 parent 视图访问它的。

你的结果将是:

如您所见,当我单击标题为 Change Container label text 的按钮时,来自 ContainerViewController 的标签文本设置为空字符串。

有关详细信息,请查看 THIS 演示项目。

我已经提出了 2 个解决这个问题的方法,而父视图控制器不知道它的子类。

在第一个示例中,父级在自身上设置子级监听的属性(通过 didSet 方法,然后相应地更新其视图。但是,这并不理想,因为 entryDateentry 字符串字段本身是无用的,在父级中几乎是多余的。

class ParentViewController: UIViewController {

    var entryDate: String?
    var entry: String?

    @IBAction func leavingView(){
        self.entryDate = ""
        self.entry = ""
        self.dismiss(animated: true, completion: nil)
    }
}

class ChildViewController: ParentViewController {

    @IBOutlet var entryDateLabel: UILabel!
    @IBOutlet var entryLabel: UILabel!

    override var entryDate: String? {
        didSet {
            guard isViewLoaded else {
                return
            }
            entryDateLabel.text = entryDate
        }
    }

    override var entry: String? {
        didSet {
            guard isViewLoaded else {
                return
            }
            entryLabel.text = entry
        }
    }
}

在我看来,第二种解决方案更清晰并且使实现细节更加独立,因为您正在使用指令或事件来通知子视图控制器。

class ParentViewController: UIViewController {

    @IBAction func leavingView(){
        self.dismiss(animated: true, completion: didLeaveView)
    }

    func didLeaveView() { }
}

class ChildViewController: ParentViewController {

    @IBOutlet var entryDateLabel: UILabel!
    @IBOutlet var entryLabel: UILabel!

    override func didLeaveView() {
        entryDateLabel.text = ""
        entryLabel.text = ""
    }

}