xcode 如何观察用户编辑UIAlertController中的textField?

vdzxcuhz  于 2022-11-17  发布在  其他
关注(0)|答案(3)|浏览(122)

我有一个UIAlertController和一个textField。由于我不能为textField创建一个插座,我必须找到另一种方法来获得一个实时观察用户输入的功能。
我已经做了一些尝试,但是没有成功。这个线程解释了如何向textField添加目标:
How do I check when a UITextField changes?

textfield.addTarget(self, action: #selector(ViewControllerr.textFieldDidChange(_:)), for: UIControl.Event.editingChanged)

我尝试了这个,但不太明白#selector输入.它想要我的UIViewController?还是我的UIAlertController我尝试了两个,但得到了相同的错误信息:
Value of type 'UIViewController' has no member 'textFieldDidChange'
UIAlertController相同。
我还尝试将我的textField设置为委托访问该类的函数:

textField.delegate = self as? UITextFieldDelegate

但我想这不是正确的方法,因为我仍然无法访问任何功能,除非执行以下操作:

textField.delegate?.textFieldDidBeginEditing?(textField)

但那也没给予我什么。
我还尝试添加一个扩展名,如下所示:

extension UITextFieldDelegate {
    func textFieldDidBeginEditing(_ textField: UITextField) {
        print("🦋EDITING")
}// became first responder

    func textFieldDidEndEditing(_ textField: UITextField) {
        print("🦋EDITING")
    }
}

但由于某种原因,我无法通过textView访问它们
如果我像这样扩展类:

extension PickNumberViewController: UITextFieldDelegate {...}

我收到相同的错误消息

Value of type 'UITextField' has no member 'textFieldDel...'

这没有意义,因为我将textField设置为UITextFieldDelegate而不是UITextField
如果您也想查看我的代码,请告诉我。

bfnvny8b

bfnvny8b1#

可以尝试使用self.textF = alert.textFields?[0]获取对它的引用

class ViewController: UIViewController {

    var textF:UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {

            //1. Create the alert controller.
            let alert = UIAlertController(title: "Some Title", message: "Enter a text", preferredStyle: .alert)
            alert.addTextField { (textField) in
                textField.text = "Some default text"
            }
             let tex = alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in

            })) 
            // 4. Present the alert.
            self.present(alert, animated: true, completion: nil)

            self.textF =  alert.textFields?[0]

            self.textF.addTarget(self, action: #selector(self.textFieldDidChange), for: UIControl.Event.editingChanged)

        }

    }

    @objc func textFieldDidChange() {
        print(textF.text)
    }

}
e4eetjau

e4eetjau2#

你不需要保存对文本字段的引用,你可以在addTextField闭包中添加target或者设置delegate,如下所示。

class ViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let alert = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert)
        alert.addTextField { textField in
            textField.delegate = self
            textField.addTarget(self, action: #selector(self.textChanged(_:)), for: .editingChanged)
            textField.placeholder = "Enter name"
        }
        alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
        present(alert, animated: true, completion: nil)
    }
    @objc func textChanged(_ sender: UITextField) {
        print("Text changed - ", sender.text!)
    }
}
extension ViewController: UITextFieldDelegate {
    func textFieldDidBeginEditing(_ textField: UITextField) {
        print("EDITING")
    }
    func textFieldDidEndEditing(_ textField: UITextField) {
        print("EDITING")
    }
}
xcitsw88

xcitsw883#

iOS13+一种选择是使用UIAction

extension UIAlertController {

public func addTextField(_ configuration: @escaping ((UITextField) -> Void),
                         onEditingDidBegin: ((UITextField) -> Void)? = nil,
                         onEditingChanged: ((UITextField) -> Void)? = nil,
                         onEditingDidEnd: ((UITextField) -> Void)? = nil) {
    self.addTextField { textField in
        configuration(textField)
        if let onEditingDidBegin {
            textField.addAction(UIAction { action in
                onEditingDidBegin(action.sender as! UITextField)
            }, for: .editingDidBegin)
        }
        if let onEditingChanged {
            textField.addAction( UIAction { action in
                onEditingChanged(action.sender as! UITextField)
            }, for: .editingChanged)
        }
        if let onEditingDidEnd {
            textField.addAction( UIAction { action in
                onEditingDidEnd(action.sender as! UITextField)
            }, for: .editingDidEnd)
        }
    }
}

这样使用:

let alert = UIAlertController(title: "Enter Text", message: nil, preferredStyle: .alert)
alert.addTextField { textField in
        textField.text = "Some text"
        textField.placeholder = "Placeholder"
    } onEditingDidBegin: { textField in
        textField.selectAll(nil) // selects all text
    } onEditingChanged: { textField in
        if let text = textField.text {
            textField.textColor = text.count > 5 ? .red : .label
        }
    } onEditingDidEnd: { textField in
        if let text = textField.text {
            if text.count > 5 {
                textField.text = "This is too long"
            }
        }
    }

但是,您不应该使用onEditingDidEnd来进行最终验证,请将其放入UIAlertAction中,作为“OK”按钮,然后取出textFields:

let okAction = UIAlertAction(title: "OK", style: .destructive) { [weak self, weak alert] _ in
        if let self,
           let alert,
           let textField = alert.textFields?.first {
            // validate (here, 'self', is a view controller)
            self.label.text = textField.text
        }
}
alert.addAction(okAction)

相关问题