web-dev-qa-db-fra.com

Empêcher UIAlertController de rejeter

Je voudrais empêcher le UIAlertController de congédier. 

J'ai un UIAlertAction qui ajoute simplement une chaîne dans le UIAlertTextField, cependant, une fois appuyé, il ferme le contrôleur de vue [non désiré]. J'ai essayé d'ajouter une NSNotification avec des résultats indésirables.

    UIAlertAction *pasteMessage = [UIAlertAction actionWithTitle:@"Paste Message" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        UITextField *textField = alertC.textFields.firstObject;
        textField.text = [textField.text stringByAppendingString:[NSString stringWithFormat:@"%@", copiedString]];
    }];

J'ai aussi essayé de ne pas coller à message par:

 [alertC canPerformAction:@selector(dismissViewControllerAnimated:completion:) withSender:pasteMessage];

-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {
    UIAlertController *alertController = (UIAlertController *)self.presentedViewController;
    UIAlertAction *paste = alertController.actions.firstObject;
       if (paste) {
         flag = NO;
       } else {
         flag = YES;
       }
 }

Modifier, je ne cherche pas à empêcher l’écoute de UIAlertAction mais plutôt à empêcher la UIAlertController de fermer les yeux lorsque vous appuyez sur ladite action. L'action peut être activée/désactivée de quelque manière que ce soit, mais mon objectif est simplement de coller le message copié dans la variable UITextField en appuyant sur une action (d'où la raison pour laquelle je ne souhaite pas qu'il soit rejeté).

Je me rends également compte que le paramétrage de BOOL sur dismissViewControllerAnimated: le configure simplement sur non pour animer le licenciement des contrôleurs de vue, je ne veux pas que cela implique que le processus de licenciement a été arrêté. Offrir simplement les choses que j'ai essayées par rapport à mon objectif. J'ai également essayé de présenter un nouveau UIAlertController lors de la sélection de pasteMessage, qui remplit automatiquement le newUIAlertControllers textField avec le message copié, cela fonctionne, mais j'ai l'impression que c'est trop compliqué pour ce qui pourrait être fait.

26
soulshined

MODIFIER:

Mise à jour pour Swift 3

Donc, en fait, ça a fonctionné. En bref, cela implique l’ajout d’un identificateur de geste à la variable UIAlertController qui se déclenche avant le licenciement.

Tout d’abord, vous créez des variables calculées chargées paresseusement pour votre UIAlertController et la UIAlertAction que vous souhaitez empêcher de se déclencher sur votre contrôleur de vue, de sorte qu’elles soient accessibles par la méthode de sélection du programme de reconnaissance de mouvements (self dans le sélecteur), insinuant que tout cela est dans une vue. manette).

lazy var alert: UIAlertController = {

    let alert = UIAlertController(title: "Title", message: "Message", preferredStyle: .alert)

    alert.addTextField(configurationHandler: nil)

    let appendAction = self.appendAction
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

    alert.addAction(appendAction)
    alert.addAction(cancelAction)

    let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.append(sender:)))
    gestureRecognizer.minimumPressDuration = 0.0
    alert.view.addGestureRecognizer(gestureRecognizer)

    return alert
}()

lazy var appendAction: UIAlertAction = {
    return UIAlertAction(title: "Paste Message", style: .default, handler: nil)
}()

Assurez-vous que votre identificateur de geste ci-dessus est une variable UILongPressGestureRecognizer avec une durée d'appui minimale de 0. De cette manière, vous pouvez accéder à l'état du geste (lorsque l'utilisateur touche le bouton) avant que l'action ne soit entièrement déclenchée. Là, vous pouvez désactiver la variable UIAlertAction, implémenter votre code personnalisé et réactiver l’action une fois le geste terminé (l’utilisateur a retouché). Voir ci-dessous:

@objc func append(sender: UILongPressGestureRecognizer) {

    if sender.state == .began {
        appendAction.isEnabled = false
    } else if sender.state == .ended {
        // Do whatever you want with the alert text fields
        print(alert.textFields![0].text)
        appendAction.isEnabled = true
    }
}

Ensuite, il vous suffit de présenter la UIAlertController où que vous soyez.

@IBAction func showAlert(sender: AnyObject) {
    self.present(alert, animated: true, completion: nil)
}

C'est évidemment un bidouillage, mais il n'y a pas d'autre moyen que je connaisse pour y parvenir sans un bidouillage, car ce n'est pas censé être réalisé. Par exemple, la reconnaissance des gestes est liée à la UIAlertController afin que l'utilisateur puisse déclencher cette méthode s'il appuie n'importe où sur l'alerte (en plus du bouton d'annulation).

RÉPONSE ORIGINALE:

Ceci est aussi proche que je pourrais arriver à un hackaround. S'il existait un moyen de personnaliser le temps de transition de renvoi à néant, vous pouvez définir animated: sur false et ressembler à la même alerte, mais je ne pense pas que ce soit possible.

class ViewController: UIViewController {

    @IBAction func alert(sender: AnyObject) {
        let alert = UIAlertController(title: "title", message: "message", preferredStyle: .Alert)

        alert.addTextFieldWithConfigurationHandler(nil)

        let appendAction = UIAlertAction(title: "Append text", style: .Default) { _ in
            var textField = alert.textFields![0] as UITextField
            // Append text here
            self.presentViewController(alert, animated: true, completion: nil)
        }

        let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)

        alert.addAction(appendAction)
        alert.addAction(cancelAction)

        self.presentViewController(alert, animated: true, completion: nil)
    }
}

Je ne connais que Swift

24
Aaron

On répond à peu près à la même question ici

Le champ de texte en alerte prend en charge l'option coller, il n'y a donc aucune raison d'avoir un bouton séparé en alerte pour indiquer l'option "coller".

Sinon, vous devez imiter UIAlertController et le réimplémenter avec un comportement désiré. 

0