防止解除UIAlertController

我将一个UITextField添加到一个UIAlertController ,它显示为一个AlertView 。 在解除UIAlertController之前,我想validationUITextField的input。 基于validation我想解雇UIAlertController或不。 但是我不知道如何在按下button时阻止UIAlertController的解除操作。 有没有人解决了这个问题或任何想法从哪里开始? 我去了谷歌,但没有运气:/谢谢!

你是正确的:如果用户可以点击一个button,警报将被解散。 所以你想阻止用户点击button! 这只是closures您的UIAlertActionbutton的问题。 如果警报操作被禁用,则用户不能点击它来解除。

要将其与文本字段validation结合使用,可以使用文本字段委托方法或操作方法(在创build时在文本字段的configuration处理程序中进行configuration)根据input(或未input)的文本来适当地启用/禁用UIAlertAction 。

这是一个例子。 我们创build了这样的文本字段:

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

我们有一个“取消”操作和一个“确定”操作,我们将OK操作带入禁用的世界:

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

随后,用户不能点击确定,除非在文本字段中有一些实际的文本:

 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 

 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 != "") } 

我已经简化了马特的答案,没有视图遍历遍历。 这是把行动本身作为一个弱variables来代替。 这是一个完全可行的例子:

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

从@ 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); } 

我意识到这是在Objectiv-C中,但它显示了委托人。 我会稍后用一个很快的版本来更新它。

您也可以使用块作为目标。

添加一个属性到你的ViewController以便该块(swift的闭包)有一个强有力的参考

@property (strong, nonatomic) id textValidationBlock;

然后像这样创buildAlertViewController

 UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) { }]; __weak typeof(self) weakSelf = self; UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { [weakSelf doSomething]; }]; [alertController addAction:cancelAction]; [alertController addAction:okAction]; [alertController.actions lastObject].enabled = NO; self.textValidationBlock = [^{ UITextField *textField = [alertController.textFields firstObject]; if (something) { alertController.message = @"Warning message"; [alertController.actions lastObject].enabled = NO; } else if (somethingElse) { alertController.message = @"Another warning message"; [alertController.actions lastObject].enabled = NO; } else { //Validation passed alertController.message = @""; [alertController.actions lastObject].enabled = YES; } } copy]; [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { textField.placeholder = @"placeholder here"; [textField addTarget:weakSelf.textValidationBlock action:@selector(invoke) forControlEvents:UIControlEventEditingChanged]; }]; [self presentViewController:alertController animated:YES completion:nil];