如何使用#selector函数传递变量?传递给textField:UITextField的内容是什么?

时间:2017-05-26 12:49:54

标签: ios swift swift3

所以我有一个带有2个文本字段的UIAlertController,然后我想监视每次编辑这些文本字段以查看它们是否符合某个标准。

在这种情况下,只要两个文本字段输入都短于我要传递给函数的数字,我希望我的警报按钮处于非活动状态。

所以我将这个目标添加到两个文本字段中:

textField.addTarget(self,action:#selector(self.handleTextFieldEdit),for:.editingChanged)

在handleTextFieldEdit里面我有这个:

func handleTextFieldEdit(_ textField: UITextField, number: Int)
{
    let number = number
    let alertController:UIAlertController = self.presentedViewController as! UIAlertController;
    let textField: UITextField  = alertController.textFields![0]
    let confirmField: UITextField = alertController.textFields![1]
    let addAction: UIAlertAction = alertController.actions[0];

    if ((textField.text?.characters.count)! > number && (confirmField.text?.characters.count)! > number)
    {
        addAction.isEnabled = true
    }
    else if ((textField.text?.characters.count)! <= number || (confirmField.text?.characters.count)! <= number )
    {
        addAction.isEnabled = false
    }
}

现在我的第一个问题是我似乎无法通过#selector func传递任何变量。

我的第二个问题是我不知道要传递给_ textField的内容:UITextField

我已经尝试了UITextField和textField(这是我向UITextFields声明的内容)。

出现的错误是:无法将类型&#39; UITextField&#39; .Type的值转换为预期参数类型&#39; UITextField&#39;。

编辑:只要我没有通过函数btw传递变量,我的所有代码都可以正常工作。问题是我想在调用函数时更改最小值。

5 个答案:

答案 0 :(得分:2)

您正在尝试向IBAction选择器添加EXTRA参数(int)。你不能这样做。 IBActions有3个选择器之一:

@IBAction func actionNoParams() {
}

@IBAction func actionWSender(_ sender: Any) {
}

@IBAction func actionWSenderAndEvent(_ sender: Any, forEvent event: UIEvent) {
}

这是你唯一的选择。您无法添加其他参数,也无法更改任何可能参数的类型。

当控件需要调用目标/操作时,系统会调用您的函数。

(每当您向控件添加目标/操作时,您必须使用上面的某个功能签名,即使您没有使用@IBAction关键字标记您的功能(您应该真正使用做,BTW。)

答案 1 :(得分:1)

这是一些经过测试的代码。基本上,我已经将UIAlertViewController子类化,添加了添加UITextFieldsUIAlertAction的函数。

通过传递包含最小长度和占位符值的元组(Int,String)来创建文本字段。创建时禁用“确定”按钮。

在内部,我添加了您的handleTextFieldEdit()函数,但重构了。它在第二个数组中设置Bool - 您可以简单地使用单个数组,但这只是一个示例 - 然后调用新函数来设置okButton.isEnabled属性。

在我的UIViewController

public func showAlert(_ title:String, _ message:String) {

    // use the subclassed UIAlertViewController
    //   - add two text fields with minimum length and placeholders
    //   - add an OK button

    let alertVC = MyAlertController(
        title: "MyTitle",
        message: "MyMessage",
        preferredStyle: .alert)
    alertVC.addTextFields([(5,"Enter First Name"),(10,"Enter Last Name")])
    alertVC.addOkAction()

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

我的子类UIAlertViewController:

class MyAlertController: UIAlertController {

    var textMinLengths = [Int]()
    var textMinLengthsReached = [Bool]()
    var okAction:UIAlertAction!

    // add UITextFields:
    //   - append textMinLengths[]
    //   - set placeholder
    //   - append "false" to textMinLengthsReached[]
    //   - set tag value to array index
    //   - add target action handleTextFieldEdit()

    func addTextFields(_ textConfigs:[(Int,String)]) {
        var tagValue:Int = 0
        for textConfig in textConfigs {
            textMinLengths.append(textConfig.0)
            textMinLengthsReached.append(false)
            self.addTextField { (textField : UITextField!) -> Void in
                textField.placeholder = textConfig.1
                textField.tag = tagValue
                textField.addTarget(self, action: #selector(self.handleTextFieldEdit(_:)), for: .editingChanged)            }
            tagValue += 1
        }
    }

    // add a *disabled* OK button

    func addOkAction() {
        okAction = UIAlertAction(
            title: "OK",
            style: .cancel,
            handler: { action -> Void in
        })
        self.addAction(okAction)
        okAction.isEnabled = false
    }

    // every keystroke, check the character count against the minimum, setting if it's been reached,
    // always checking whether to show alert action afterwards

    func handleTextFieldEdit(_ sender: UITextField) {
        if (sender.text?.characters.count)! >= textMinLengths[sender.tag] {
            textMinLengthsReached[sender.tag] = true
        } else {
            textMinLengthsReached[sender.tag] = false
        }
        showAlertAction()
    }

    // loop through textMinLengthsReached, setting okButton.isEnabled

    func showAlertAction() {
        var isEnabled = true
        for textMinLengthReached in textMinLengthsReached {
            if !textMinLengthReached {
                isEnabled = false
                break
            }
        }
        okAction.isEnabled = isEnabled
    }
}

答案 2 :(得分:0)

尝试以下代码

textField.addTarget(self, action: #selector(self.handleTextFieldEdit(sender:)), for: .editingChanged)

func handleTextFieldEdit(sender: UITextField) {
}

答案 3 :(得分:0)

为了跟踪文本字段中的更改,某些对象必须是此文本字段的委托

例如,当您创建带有文本字段的AlertController时,您应该为其分配委托。

某些YourViewController的方法内部:

self.alertView = UIAlertController.init(title: "Your title", message: Your message", preferredStyle: .alert)
self.alertView.addTextField(configurationHandler: { textfield in
textfield.font = UIFont.fontProximaNovaLight(18)
textfield.textColor = UIColor.colorAppLightGray2()
textfield.keyboardType = .default
textfield.delegate = self 
})

扩展您的viewController:

extension YourViewController: UITextFieldDelegate {

    func textField(_ textField: UITextField,
                   shouldChangeCharactersIn range: NSRange,
                   replacementString string: String) -> Bool {

        let text = textField.text?.replacingCharacters( in: range.toRange(textField.text!), with: string)
        // some test verification
        // for example you can use your function to verify textfield against value
        // validate (textfield, number)



        if text?.characters.count > 0 {
            self.alertView.actions[0].isEnabled = true
        } else {
            self.alertView.actions[0].isEnabled = false
        }

        return true
    }
}

答案 4 :(得分:0)

子类UITextField并添加另一个属性以用于您的长度要求。然后您可以将其作为发件人的一部分阅读。