【问题标题】:How to pass a variable with a #selector function?And what to pass to textField: UITextField?如何使用#selector 函数传递变量?以及将什么传递给textField:UITextField?
【发布时间】:2017-10-27 09:04:32
【问题描述】:

所以我有一个 UIAlertController,有 2 个文本字段,然后我想在编辑这些文本字段时监控它们是否符合特定条件。

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

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

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 的)。

出现的错误是:无法将“UITextField”类型的值转换为预期的参数类型“UITextField”。

编辑:只要我不使用函数 btw 传递变量,我的所有代码都可以工作。问题是我希望在调用函数时更改最小值。

【问题讨论】:

    标签: ios swift swift3


    【解决方案1】:

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

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

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

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

    (任何时候你添加一个目标/动作到一个控件,你必须使用上面的函数签名之一,即使你没有用@IBAction关键字标记你的函数(你真的应该这样做,顺便说一句。 )

    【讨论】:

    • 为什么要在我的代码中添加@IBAction?这不是只用于情节提要吗?
    • 这是个好习惯。它表明该函数正在被目标/动作中的控件调用。
    【解决方案2】:

    这是一些经过测试的代码。基本上,我对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
        }
    }
    

    【讨论】:

    • 非常感谢您的详细回答!
    【解决方案3】:

    试试下面的代码

    textField.addTarget(self, action: #selector(self.handleTextFieldEdit(sender:)), for: .editingChanged)
    
    func handleTextFieldEdit(sender: UITextField) {
    }
    

    【讨论】:

    • 我不确定这将如何解决我的问题?你能再解释一下吗?
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      为了跟踪文本字段的变化,一些对象必须是这个文本字段的代表

      例如,当您创建带有文本字段的 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
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-28
        • 1970-01-01
        • 1970-01-01
        • 2018-11-10
        相关资源
        最近更新 更多