UIButton 如何同时监听对其他按钮的更改、对 UILabel 文本的更改以及对 UITextView 的更改

How can a UIButton listen to changes to other Buttons, a change to a UILabel's text, and a change to a UITextView all at the same time

我的 vc 包含:

-1 名称 textView

-1 标签 // 口味

-2 个单选按钮 // 是和否

-1 下一个按钮

我想要做的是保持 nextButton 处于禁用状态,直到 textView 被填充,标签的文本值从其初始标题 "Pick a Flavor" 更改为他们选择的任何风格,以及 1 个单选按钮被选中。

我知道使用 textView 的 textViewDidEndEditing() 我可以在用户完成编辑禁用或启用 nextButton 后监听它的变化。

func textViewDidEndEditing(_ textView: UITextView) {
    handleTextInputChanged()
}

@objc func handleTextInputChanged() {
    let isFormValid = nameTextView.text?.count ?? 0 > 0

    if isFormValid {
        nextButton.isEnabled = true
        nextButton.backgroundColor = .red
    } else {
        nextButton.isEnabled = false
        nextButton.backgroundColor = .lightgray
    }
}

除了检查 nameTextView 中是否包含文本之外,我如何根据是否选择了其中一个单选按钮并更改标签的文本来另外禁用或启用 nextButton?

仅供参考,标签的文本最初设置为 "Pick a Flavor"。我有一个连接到它的手势识别器,当它点击一个带有 tableView 的新 vc 时。用户选择一种口味,协议将其发送回此 vc 并且标签的文本将更改为所选的任何口味(例如,如果选择,标签的标题将显示 "Butter Pecan" )。只要标签的标题仍设置为 "Pick a Flavor".

,就应该禁用 nextButton

代码:

let flavorLabel: UILabel = {
    let label = UILabel()
    label.text = "Pick a Flavor"
    label.isUserInteractionEnabled = true
    return label
}()

let nameTextView: UITextView = {
    let textView = UITextView()
    return textView
}()

let noButton: DLRadioButton = {
    let button = DLRadioButton(type: .custom)
    button.setTitle("No", for: .normal)
    button.setTitleColor(UIColor.lightGray, for: .normal)
    button.addTarget(self, action: #selector(noButtonPressed), for: .touchUpInside)
    return button
}()

let yesButton: DLRadioButton = {
    let button = DLRadioButton(type: .custom)
    button.setTitle("Yes", for: .normal)
    button.setTitleColor(UIColor.lightGray, for: .normal)
    button.addTarget(self, action: #selector(yesButtonPressed), for: .touchUpInside)
    return button
}()

let nextButton: UIButton = {
    let button = UIButton(type: .system)
    button.setTitle("Next", for: .normal)
    button.setTitleColor(UIColor.white, for: .normal)
    button.isEnabled = false
    button.backgroundColor = .lightGray
    button.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
    return button
}()

var choice: Bool?

override func viewDidLoad() {
    super.viewDidLoad()

    flavorVC.delegate = self
}

func textViewDidEndEditing(_ textView: UITextView) {
    handleTextInputChanged()
}

@objc func handleTextInputChanged() {
    let isFormValid = nameTextView.text?.count ?? 0 > 0

    if isFormValid {
        nextButton.isEnabled = true
        nextButton.backgroundColor = .red
    } else {
        nextButton.isEnabled = false
        nextButton.backgroundColor = .lightgray
    }
}

@objc fileprivate func noButtonPressed() {
    choice = false
}

@objc fileprivate func yesButtonPressed() {
    choice = true
}

// delegate method from FlavorController
func selectedFlavor(flavor: String) {

    flavorLabel.text = flavor // eg. "Butter Pecan"
}

你需要创建一个像这样检查所有的函数

func checkAll() {
    nextButto.isEnabled = flavorLabel.text != "Pick a Flavor" &&
    nameTextField.text != "" &&
    (noButton.someProerty != || yesButton.someProerty != )
}

并从文本字段和按钮目标加上

调用它
var ob:NSKeyValueObservation?

ob = flavorLabel.observe(\.text,options:[.new], changeHandler: { [unowned self] _, change in

   self.checkAll()
}

我留下了单选检查,因为它们都是自定义的,所以你应该知道要检查什么,顺便说一句,你可以在目标方法中将 selected 的标签设置为 1 并根据它或你想要的其他逻辑进行检查