2015-03-07 15 views
23

Vorrei impedire allo UIAlertController di chiudere.Previene UIAlertController per respingere

Ho un UIAlertAction che aggiunge semplicemente una stringa a UIAlertTextField, tuttavia, dopo averlo toccato, chiude il controller di visualizzazione [indesiderato]. Ho provato ad aggiungere una NSNotification con risultati indesiderati.

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

Ho anche provato a installare no a pasteMessage da:

[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; 
     } 
} 

Modifica, non sto cercando di impedire le intercettazioni delle UIAlertAction sto cercando di evitare che il UIAlertController da respingere quando si tocca su detta azione. L'azione può essere abilitata/disabilitata, ma il mio obiettivo è semplicemente incollare il messaggio copiato nello UITextField premendo un'azione (da qui il motivo per cui non voglio che venga ignorato)

Mi rendo anche conto dell'impostazione di BOOL a dismissViewControllerAnimated: imposta semplicemente a non animare il congedo dei controller di visualizzazione, non voglio che implichi che fosse per fermare il processo di licenziamento effettivo. Semplicemente offrendo le cose che ho provato in relazione al mio obiettivo. Ho anche provato presentando una nuova UIAlertController quando si seleziona pasteMessage auto-popolare la nuova UIAlertControllers textField con il messaggio copiato, funziona, ma mi sento come se fosse troppo hacky per quello che potrebbe essere fatto.

+0

possibile duplicato di [Impedisci il licenziamento di UIAlertController] (http://stackoverflow.com/questions/25628000/prevent-dismissal-of-uialertcontroller) –

+0

Grazie @LyndseyScott questa non è una vera soluzione alla mia domanda. Questo impedisce semplicemente che un pulsante sia abilitato in base al campo di testo che contiene del testo: ecco la loro soluzione: '= (tf.text! =" ")' Che disabilita semplicemente il pulsante dal permettere che la vista venga ignorata _eventualmente_ – soulshined

+0

Ma penso la parte più pertinente di tale risposta è la selezione di un 'UIAlertAction' * che * eliminerà il tuo avviso. Se vuoi qualche altro comportamento, prova a creare la tua vista personalizzata. –

risposta

21

EDIT:

aggiornato per Swift 3

Così ho effettivamente avuto questo lavoro. In breve, comporta l'aggiunta di un riconoscitore di gesti allo UIAlertController che si innesca prima che si verifichi il licenziamento.

In primo luogo, è necessario creare pigramente caricato variabili calcolate per il UIAlertController e UIAlertAction si vuole impedire di innescare sul controller della vista in modo che siano accessibili con il metodo di selezione del riconoscitore gesto (self nel selettore insinua che tutto questo è all'interno di un controller di visualizzazione).

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) 
}() 

Assicurarsi che il sistema di riconoscimento gesto di cui sopra è un insieme UILongPressGestureRecognizer con una durata minima stampa pari a 0. In questo modo è possibile accedere allo stato del gesto (per quando l'utente tocca verso il basso) prima che l'azione viene attivata completamente. Qui puoi disabilitare lo UIAlertAction, implementare il tuo codice personalizzato e riabilitare l'azione dopo che il gesto è stato completato (l'utente ha ritoccato). Vedi sotto:

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

Quindi devi solo presentare il UIAlertController ovunque.

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

Si tratta ovviamente di un hack, ma non c'è altro modo che conosco per raggiungere questo obiettivo, senza un hack in quanto non è pensato per essere raggiunto. Ad esempio, il riconoscitore di gesti è legato allo UIAlertController in modo che l'utente possa attivare tale metodo se tocca ovunque sull'avviso (oltre al pulsante Annulla).

RISPOSTA ORIGINALE:

Questo è il più vicino ho potuto venire a una hackaround. Se ci fosse un modo per personalizzare il tempo il licenziamento di transizione a nulla allora si potrebbe impostare animated: false e sarebbe simile lo stesso avviso, ma non credo che sia possibile

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

io sono solo familiarità con swift

+0

Swift non è un problema. Facilmente traducibile Tuttavia, non sono a un computer per problemi di ripresa, ma sono abbastanza sicuro che il tuo codice causerà un errore. Stai provando a presentare un controller di visualizzazione sullo stesso già esistente. Inoltre, re i suoi commenti su impostazione di animazione per falso, vedere la mia modifica che ho fatto in precedenza prima della risposta, è stata la 'soluzione' ho fatto, ma io non sono felice con lui come una risoluzione che è il motivo per cui ho finito per chiedere qui – soulshined

+0

Ho eseguito il codice nel simulatore e ha funzionato correttamente. Non ho visto la tua modifica, la mia cattiva – Aaron

+0

La soluzione da seguire era il mio lavoro. Voto per lo sforzo. Grazie per l'input. Sto solo creando il mio DIO – soulshined

0

Praticamente la stessa domanda si risponde here

campo di testo in allerta supporta l'opzione di pasta, quindi non c'è alcun motivo reale per avere pulsante separato in allerta per indicare l'opzione "incolla".

In caso contrario, è necessario simulare UIAlertController e reimplementarlo con il comportamento del contenitore.

+0

Non è la stessa domanda. Vedi i miei commenti sopra. Quella domanda è per la convalida del testo. La mia domanda è severamente vietare il licenziamento. E c'è una vera ragione per la mia circostanza. Solo perché c'è un opzione di pasta non significa che ricorda gli ultimi 10 paste. Sarà incollato solo l'ultimo copiato negli Appunti. Il mio pulsante di pasta è un Singleton che ha ricordato app vasta trascurando l'opzione pasta di iPhone (che modo gli utenti possono utilizzare che anche se vogliono). Grazie per l'ingresso se - meglio qualcosa di niente. – soulshined

Problemi correlati