Ios 如何根据UITextField禁用UIAlertAction?

Ios 如何根据UITextField禁用UIAlertAction?,ios,swift,uitextfield,action,uialertview,Ios,Swift,Uitextfield,Action,Uialertview,我有一个操作,当点击按钮时,它会创建一个警报 此警报由两个文本字段和两个操作(添加和解除)组成 如果文本字段为空,有没有简单的方法可以禁用添加按钮(稍后我会检查第二个字段是否真的是URL,但让我们关注操作 以下是我的代码和我迄今为止尝试的内容: @IBAction func addSourceTapped(_ sender: Any) { let alert = UIAlertController(title: "Add a News Source", message: nil, pr

我有一个
操作
,当点击按钮时,它会创建一个
警报

警报
由两个
文本字段
和两个
操作
添加
解除
)组成

如果
文本字段
为空,有没有简单的方法可以禁用
添加
按钮(稍后我会检查第二个字段是否真的是URL,但让我们关注
操作

以下是我的代码和我迄今为止尝试的内容:

@IBAction func addSourceTapped(_ sender: Any) {

    let alert = UIAlertController(title: "Add a News Source", message: nil, preferredStyle: .alert)

    alert.addTextField { (textField) in
        textField.placeholder = "Name"
    }
    alert.addTextField { (textField) in
        textField.placeholder = "Link"
    }

    let name = alert.textFields!.first!.text!
    let link = alert.textFields!.last!.text!

    if name != "" && link != "" {
        alert.actions[0].isEnabled = true
    }

    let action = UIAlertAction(title: "Add", style: .default) { (_) in
        let name = alert.textFields!.first!.text!
        let link = alert.textFields!.last!.text!

        if name != "" && link != "" {

            alert.actions[0].isEnabled = true //doesn't do anything yet..

            if CoreDataHandler.saveSource(name: "\(name)", link: "\(link)") {
                for _ in CoreDataHandler.fetchSource()! {
                }
            }
        }


        self.tableView.reloadData()
    }

    let action2 = UIAlertAction(title: "Dismiss", style: .default)

    alert.addAction(action)
    alert.actions[0].isEnabled = false
    alert.addAction(action2)
    present(alert, animated: true, completion: nil)

}

您不能在任何地方编写UITextField验证代码(用于启用/禁用操作的代码)!!。每次更新UItextfield时都必须进行此验证。因此,要做到这一点,您需要从UITextField获取委托以进行更新

您需要全局保存文本字段,并将文本字段的委托分配给ViewController。通过这样做,您可以编写代码来验证UIViewController中文本字段的代码,并以编程方式启用或禁用您的操作

class YOUR_CLASS_NAME:UIViewController,UITextFieldDelegate {

    var alert: UIAlertController!
    var action: UIAlertAction!
    var action2: UIAlertAction!
    var nameTextFeld:UITextField!
    var linkTextFeld:UITextField!

    @IBAction func addSourceTapped(_ sender: Any) {
        alert = UIAlertController(title: "Add a News Source", message: nil, preferredStyle: .alert)
        alert.addTextField { (textField) in
            self.nameTextFeld = textField
            self.nameTextFeld.placeholder = "Name"
            self.nameTextFeld.delegate = self
        }
        alert.addTextField { (textField) in
            self.linkTextFeld = textField
            self.linkTextFeld.placeholder = "Link"
            self.linkTextFeld.delegate = self
        }

        action = UIAlertAction(title: "Add", style: .default) { (_) in
            let name = self.alert.textFields!.first!.text!
            let link = self.alert.textFields!.last!.text!
            if CoreDataHandler.saveSource(name: "\(name)", link: "\(link)") {
              for _ in CoreDataHandler.fetchSource()! {

              }
            }
            self.tableView.reloadData()
        }
        action.isEnabled = false
        action2 = UIAlertAction(title: "Dismiss", style: .default)
        alert.addAction(action)
        alert.actions[0].isEnabled = false
        alert.addAction(action2)
        present(alert, animated: true, completion: nil)
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        if !((nameTextFeld.text?.isEmpty)! && (linkTextFeld.text?.isEmpty)!) {
            action.isEnabled = true
        }
        return true
    }
}

通过在添加文本字段时配置文本字段来完成此操作

alert.addTextField(configurationHandler: { (textField) -> Void in
    textField.placeholder = "Name"
    // Other configuration such as textField.autocapitalizationType = .words

    NotificationCenter.default.addObserver(forName: NSNotification.Name.UITextFieldTextDidChange, object: textField, queue: OperationQueue.main) { (notification) in
        let nameField = alert.textFields![0] as UITextField
        let linkField = alert.textFields![1] as UITextField

        action.isEnabled = self.getTextFieldContent(nameField) != "" && self.getTextFieldContent(linkField) != ""
    }
})
您需要对这两个文本字段分别执行此操作(尽管您可以通过重用相同的代码来执行此操作)。另外请注意,如果您直接在操作的处理程序块中引用textfields,它将创建一个强引用循环,并且您的控制器将不会被取消命名。要避免这种情况,请使用如下局部可为null的变量引用文本字段

var tf: UITextField?

let action = UIAlertAction(title: "Add", style: .default) { (_) in
    guard let textField = tf else {
        return;
    }
    let name = textField.text!
    // Rest the action here
}

alertController.addTextField { (textField) in
    // Configure textField here
    tf = textField
}

你应该更好地使用行动,它比其他答案更简单。如果您尝试使用委托,那么didBeginEditing和didebendediting方法将无法正确处理它。也不应更改字符在范围内,它在textfield中出现输入之前执行,因此在此处检查textfield的text属性是不正确的

private var action: UIAlertAction!

@IBAction func addSourceTapped(_ sender: Any) {

    ////////

    let alert = UIAlertController(title: "Add a News Source", message: nil, preferredStyle: .alert)

    alert.addTextField { (textField) in
        textField.placeholder = "Name"
        textField.addTarget(self, action: #selector(self.textFieldDidChange(_:)), for: .editingChanged) // <---
    }

    action = UIAlertAction(title: "Add", style: .default) { (_) in
        /////
    }
    action.isEnabled = false
    alert.addAction(action)

    ////////
}

@objc private func textFieldDidChange(_ field: UITextField) {
    action.isEnabled = field.text?.count ?? 0 > 0
}
private var action:UIAlertAction!
@iAction func addSourceTapped(\发送方:任何){
////////
let alert=UIAlertController(标题:“添加新闻源”,消息:nil,preferredStyle:.alert)
alert.addTextField{(textField)位于
textField.placeholder=“名称”
textField.addTarget(self,action:#选择器(self.textFieldDidChange(:)),for:.editingChanged)//0
}

使用操作的编程解决方案。 将按钮添加到类中,并根据文本字段中所做的更改继续更改其状态

import UIKit

final class ViewWithConfirmationController: UIViewController {
  private let askButton = UIButton()
  private let deleteAction = UIAlertAction(
    title: "Confirm",
    style: .default
  ) { _ in
    // Confirmed
  }

  init() {
    super.init(nibName: nil, bundle: nil)

    view.addSubview(askButton)

    askButton.setTitle("Call alert", for: .normal)
    askButton.addTarget(
      self,
      action: #selector(callAlert),
      for: .touchUpInside
    )
  }

  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

  @objc func callAlert() {
    let alert = UIAlertController(
      title: "Confirmation alert",
      message: """
        Do you really want to do that?

        Please type in the magic word to confirm.
      """,
      preferredStyle: .alert
    )

    alert.addTextField { textField in
      textField.placeholder = "Magic word"
      textField.addTarget(
        self,
        action: #selector(self.textFieldDidChange(_:)),
        for: .editingChanged
      )
    }

    alert.addAction(
      UIAlertAction(
        title: "Cancel",
        style: .cancel,
        handler: { _ in }
      ))

    alert.addAction(deleteAction)

    // Confirm button will disabled until user type current organisation name
    deleteAction.isEnabled = false

    present(alert, animated: true, completion: nil)
  }

  @objc private func textFieldDidChange(_ field: UITextField) {
    guard let text = field.text else {
      print("Can't get text from text field in \(#function)")
      return
    }
    deleteAction.isEnabled = !text.isEmpty
  }
}

您可以使全局可选的alertview cotroller可变,然后您可以在in-textfield delegate Methods中管理验证。这很好!您知道为什么单击“添加”时,
self.tableView.reloadData()
不再起作用了吗?