54

として表示される に を追加しUITextFieldています。を閉じる前に、 の入力を検証したいと思います。検証に基づいて、却下するかどうか。しかし、ボタンが押されたときの却下アクションを防ぐ方法がわかりません。誰かがこの問題を解決したか、どこから始めるべきか考えていますか? 私はグーグルに行きましたが、うまくいきませんでした:/ ありがとう!UIAlertControllerAlertViewUIAlertControllerUITextFieldUIAlertControllerUIAlertController

4

5 に答える 5

78

その通りです。ユーザーがアラートのボタンをタップできる場合、アラートは無視されます。したがって、ユーザーがボタンをタップできないようにする必要があります。UIAlertAction ボタンを無効にするだけです。アラート アクションが無効になっている場合、ユーザーはそれをタップして閉じることはできません。

これをテキスト フィールドの検証と組み合わせるには、テキスト フィールド デリゲート メソッドまたはアクション メソッド (作成時にテキスト フィールドの構成ハンドラーで構成) を使用して、入力された (または入力されていない) テキストに応じて UIAlertActions を適切に有効/無効にします。 .

これが例です。次のようなテキスト フィールドを作成しました。

alert.addTextFieldWithConfigurationHandler {
    (tf:UITextField!) in
    tf.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
}

キャンセル アクションと OK アクションがあり、OK アクションを無効にしました。

(alert.actions[1] as UIAlertAction).enabled = false

その後、テキスト フィールドに実際のテキストがない限り、ユーザーは [OK] をタップできません。

func textChanged(sender:AnyObject) {
    let tf = sender as UITextField
    var resp : UIResponder = tf
    while !(resp is UIAlertController) { resp = resp.nextResponder() }
    let alert = resp as UIAlertController
    (alert.actions[1] as UIAlertAction).enabled = (tf.text != "")
}

編集上記のコードの現在の(Swift 3.0.1以降)バージョンは次のとおりです。

alert.addTextField { tf in
    tf.addTarget(self, action: #selector(self.textChanged), for: .editingChanged)
}

alert.actions[1].isEnabled = false

@objc func textChanged(_ sender: Any) {
    let tf = sender as! UITextField
    var resp : UIResponder! = tf
    while !(resp is UIAlertController) { resp = resp.next }
    let alert = resp as! UIAlertController
    alert.actions[1].isEnabled = (tf.text != "")
}
于 2014-09-02T16:25:38.723 に答える
21

ビュー階層を横断せずに、マットの答えを単純化しました。これは、代わりにアクション自体を弱い変数として保持しています。これは完全に機能する例です:

weak var actionToEnable : UIAlertAction?

func showAlert()
{
    let titleStr = "title"
    let messageStr = "message"

    let alert = UIAlertController(title: titleStr, message: messageStr, preferredStyle: UIAlertControllerStyle.Alert)

    let placeholderStr =  "placeholder"

    alert.addTextFieldWithConfigurationHandler({(textField: UITextField) in
        textField.placeholder = placeholderStr
        textField.addTarget(self, action: "textChanged:", forControlEvents: .EditingChanged)
    })

    let cancel = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: { (_) -> Void in

    })

    let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (_) -> Void in
        let textfield = alert.textFields!.first!

        //Do what you want with the textfield!
    })

    alert.addAction(cancel)
    alert.addAction(action)

    self.actionToEnable = action
    action.enabled = false
    self.presentViewController(alert, animated: true, completion: nil)
}

func textChanged(sender:UITextField) {
    self.actionToEnable?.enabled = (sender.text! == "Validation")
}
于 2016-03-19T08:58:44.467 に答える
7

@Mattの答えを切り取って、これが私がObj-Cで同じことをした方法です

- (BOOL)textField: (UITextField*) textField shouldChangeCharactersInRange: (NSRange) range replacementString: (NSString*)string
{
    NSString *newString = [textField.text stringByReplacingCharactersInRange: range withString: string];

    // check string length
    NSInteger newLength = [newString length];
    BOOL okToChange = (newLength <= 16);    // don't allow names longer than this

    if (okToChange)
    {
        // Find our Ok button
        UIResponder *responder = textField;
        Class uiacClass = [UIAlertController class];
        while (![responder isKindOfClass: uiacClass])
        {
            responder = [responder nextResponder];
        }
        UIAlertController *alert = (UIAlertController*) responder;
        UIAlertAction *okAction  = [alert.actions objectAtIndex: 0];

        // Dis/enable Ok button based on same-name
        BOOL duplicateName = NO;
        // <check for duplicates, here>

        okAction.enabled = !duplicateName;
    }


    return (okToChange);
}
于 2015-11-03T01:02:38.820 に答える