web-dev-qa-db-fra.com

Vérifiez sur UIAlertController TextField pour activer le bouton

J'ai un AlertController avec un champ de texte et deux boutons: ANNULER et ENREGISTRER. Voici le code:

@IBAction func addTherapy(sender: AnyObject)
{
    let addAlertView = UIAlertController(title: "New Prescription", message: "Insert a name for this prescription", preferredStyle: UIAlertControllerStyle.Alert)

    addAlertView.addAction(UIAlertAction(title: "Cancel",
                                         style: UIAlertActionStyle.Default,
                                         handler: nil))

    addAlertView.addAction(UIAlertAction(title: "Save",
                                         style: UIAlertActionStyle.Default,
                                         handler: nil))

    addAlertView.addTextFieldWithConfigurationHandler({textField in textField.placeholder = "Title"})


    self.presentViewController(addAlertView, animated: true, completion: nil)


}

Ce que je veux faire, c'est implémenter une vérification sur le champ de texte pour désactiver le bouton SAVE lorsque le champ de texte est vide, tout comme Pictures Application d'iOS lorsque vous souhaitez créer un nouvel album. S'il vous plaît, quelqu'un peut m'expliquer quoi faire?

28
Andorath

Je créerais d'abord le alertcontroller avec l'action de sauvegarde initialement désactivée. Ensuite, lors de l'ajout du champ de texte, une notification doit être observée pour observer sa modification dans le gestionnaire et dans ce sélecteur, basculez simplement la propriété activée pour les actions de sauvegarde.

Voici ce que je dis:

//hold this reference in your class
weak var AddAlertSaveAction: UIAlertAction?

@IBAction func addTherapy(sender : AnyObject) {

    //set up the alertcontroller
    let title = NSLocalizedString("New Prescription", comment: "")
    let message = NSLocalizedString("Insert a name for this prescription.", comment: "")
    let cancelButtonTitle = NSLocalizedString("Cancel", comment: "")
    let otherButtonTitle = NSLocalizedString("Save", comment: "")

    let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)

    // Add the text field with handler
    alertController.addTextFieldWithConfigurationHandler { textField in
        //listen for changes
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleTextFieldTextDidChangeNotification:", name: UITextFieldTextDidChangeNotification, object: textField)
    }


    func removeTextFieldObserver() {
        NSNotificationCenter.defaultCenter().removeObserver(self, name: UITextFieldTextDidChangeNotification, object: alertController.textFields[0])
    }

    // Create the actions.
    let cancelAction = UIAlertAction(title: cancelButtonTitle, style: .Cancel) { action in
        NSLog("Cancel Button Pressed")
        removeTextFieldObserver()
    }

    let otherAction = UIAlertAction(title: otherButtonTitle, style: .Default) { action in
        NSLog("Save Button Pressed")
        removeTextFieldObserver()
    }

    // disable the 'save' button (otherAction) initially
    otherAction.enabled = false

    // save the other action to toggle the enabled/disabled state when the text changed.
    AddAlertSaveAction = otherAction

    // Add the actions.
    alertController.addAction(cancelAction)
    alertController.addAction(otherAction)

    presentViewController(alertController, animated: true, completion: nil)
} 

    //handler
func handleTextFieldTextDidChangeNotification(notification: NSNotification) {
    let textField = notification.object as UITextField

    // Enforce a minimum length of >= 1 for secure text alerts.
    AddAlertSaveAction!.enabled = textField.text.utf16count >= 1
}

Je fais cela dans un autre projet - j'ai obtenu ce modèle directement à partir de Apple exemples. Ils ont un très bon projet d'exemple décrivant quelques-uns de ces modèles dans les exemples UICatalog: https: //developer.Apple.com/library/content/samplecode/UICatalog/Introduction/Intro.html

27
Rufus

Il existe un moyen beaucoup plus simple sans utiliser le centre de notification, dans Swift:

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.addTextField(configurationHandler: {(textField: UITextField) in
        textField.placeholder = placeholderStr
        textField.addTarget(self, action: #selector(self.textChanged(_:)), for: .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.isEnabled = false
    self.present(alert, animated: true, completion: nil)
}

func textChanged(_ sender:UITextField) {
    self.actionToEnable?.isEnabled  = (sender.text! == "Validation")
}
50
ullstrm

Swift 3.0 Solution mise à jour fournie par @spoek

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

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

        let placeholderStr =  "placeholder"

        alert.addTextField(configurationHandler: {(textField: UITextField) in
            textField.placeholder = placeholderStr
            textField.addTarget(self, action: #selector(self.textChanged(_:)), for: .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.isEnabled = false
        self.present(alert, animated: true, completion: nil)
    }

    func textChanged(_ sender:UITextField) {
        self.actionToEnable?.isEnabled  = (sender.text! == "Validation")
    }
3
Sourabh Sharma

J'ai implémenté une sous-classe d'UIAlertController pour ajouter facilement des champs de texte et l'activation et la désactivation associées des boutons. La logique de base est similaire à celle de Sourabh Sharma mais tout est encapsulé dans cette sous-classe pour la propreté. Cela devrait être utile si votre projet implique de nombreuses fonctionnalités d'alerte.

public class TextEnabledAlertController: UIAlertController {
  private var textFieldActions = [UITextField: ((UITextField)->Void)]()

  func addTextField(configurationHandler: ((UITextField) -> Void)? = nil, textChangeAction:((UITextField)->Void)?) {
      super.addTextField(configurationHandler: { (textField) in
        configurationHandler?(textField)

        if let textChangeAction = textChangeAction {
            self.textFieldActions[textField] = textChangeAction
            textField.addTarget(self, action: #selector(self.textFieldChanged), for: .editingChanged)

        }
    })

}

  @objc private func textFieldChanged(sender: UITextField) {
    if let textChangeAction = textFieldActions[sender] {
        textChangeAction(sender)
    }
  }
}

Pour l'utiliser, il suffit de fournir un bloc textChangeAction lors de l'ajout des champs de texte:

    alert.addTextField(configurationHandler: { (textField) in
        textField.placeholder = "Your name"
        textField.autocapitalizationType = .words
    }) { (textField) in
        saveAction.isEnabled = (textField.text?.characters.count ?? 0) > 0
    }

Pour l'exemple complet, voir la page git .

1
CodeBrew