2017-05-26 74 views
2

所以我有一個UIAlertController,有2個文本框,然後我想監視每當這些文本框編輯,看看他們是否符合一定的標準。如何使用#selector函數傳遞變量?以及傳遞給textField:UITextField的內容?

在這種情況下,只要兩個文本字段的輸入都短於要傳遞給該函數的數字,我希望我的警報按鈕處於非活動狀態。

所以我加入這個目標到兩個文本框:

textField.addTarget(自我,動作:#selector(self.handleTextFieldEdit),用於:.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傳遞任何變量。

我的第二個問題是,我不知道該怎麼傳遞給_文本框:的UITextField

我曾經嘗試都的UITextField和文本框(這是我宣佈我的UITextFields到)。

出現的錯誤是:無法將類型'UITextField'.Type的值轉換爲期望的參數類型'UITextField'。

編輯:我所有的代碼工作,只要我不通過一個變量與函數btw。問題是我希望每當我調用函數時都改變最小值。

回答

0

這是一些測試代碼。基本上,我已經子類UIAlertViewController,添加功能以添加UITextFieldsUIAlertAction

通過傳遞包含最小長度和佔位符值的元組(Int,String)來創建文本字段。 OK按鈕在創建時被禁用。

在內部,我已經添加了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 
    } 
} 
+0

非常感謝您的詳細解答! – Elhoej

0

試試下面的代碼

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

func handleTextFieldEdit(sender: UITextField) { 
} 
+0

我不知道這將如何解決我的問題?你能再解釋一下嗎? – Elhoej

1

你想一個額外的參數(一個int)添加到IBAction選擇。你不能那樣做。 IBActions有3個選擇器之一:

@IBAction func actionNoParams() { 
} 

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

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

這些是你唯一的選擇。您不能添加其他參數,或者更改任一可能參數的類型。

當控件需要調用目標/動作時,系統會調用您的函數。 (任何時候當您向控件添加目標/動作時,即使您沒有使用@IBAction關鍵字標記您的功能,您也必須使用上述功能簽名之一(您應該真的在做這些事情,順便說一下)。

+0

爲什麼要將@IBAction添加到我的代碼中?是不是隻用於故事板? – Elhoej

+1

這是很好的做法。它表明函數正在被目標/動作中的控件調用。 –

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 
    } 
} 
0

子類的UITextField,並添加另一個屬性用於您的長度要求。然後,您可以將其作爲發件人的一部分閱讀。