UIAlertController处理忽略外部(IPad)

在iOS8之前,我们使用UIActionSheet来显示警报,现在我们需要使用UIAlertController。

当我们使用UIActionSheet时,我们可以很容易地处理用户在popup窗口之外单击的情况(这意味着他想要取消操作),通过比较clickedButtonAtIndex和cancelButtonIndex – 如果用户的确在button之外按下了button索引在这个function。

我们如何使用新的UIAlertController来处理这些情况? 我试图使用“完成”块,但它没有任何上下文。 有一个简单的方法来处理这个? (除了“保存”一些常规variables中的动作状态之外)。

您可以使用样式添加一个动作:UIAlertActionStyleCancel,当用户在popup窗口之外轻击时,会调用此动作的处理程序。

if ([UIAlertController class]) { UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Alert Title" message:@"A Message" preferredStyle:UIAlertControllerStyleActionSheet]; [alertController addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) { NSLog(@"User clicked button called %@ or tapped elsewhere",action.title); }]]; [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { NSLog(@"User clicked button called %@",action.title); }]]; [alertController addAction:[UIAlertAction actionWithTitle:@"Other" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action) { NSLog(@"User clicked button called %@",action.title); }]]; UIControl *aControl = (UIControl *) sender; CGRect frameInView = [aControl convertRect:aControl.bounds toView:self.view]; alertController.popoverPresentationController.sourceRect = frameInView; alertController.popoverPresentationController.sourceView = self.view; alertController.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionAny; [self presentViewController:alertController animated:YES completion:nil]; } 

针对UIAlertController使用alert方式的解决scheme。 只需要将手势识别器添加到alertController超级视图。

  [self presentViewController: alertController animated: YES completion:^{ alertController.view.superview.userInteractionEnabled = YES; [alertController.view.superview addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget: self action: @selector(alertControllerBackgroundTapped)]]; }]; - (void)alertControllerBackgroundTapped { [self dismissViewControllerAnimated: YES completion: nil]; } 

UITapGestureRecognizer没有为我工作,所以我用这种方式:

 func addDismissControl(_ toView: UIView) { let dismissControl = UIControl() dismissControl.addTarget(self, action: #selector(self.dismissAlertController), for: .touchDown) dismissControl.frame = toView.superview?.frame ?? CGRect.zero toView.superview?.insertSubview(dismissControl, belowSubview: toView) } func dismissAlertController() { self.dismiss(animated: true, completion: nil) } func presentAlertController(title: String?, message: String?, preferredStyle: UIAlertControllerStyle, handler: ((UIAlertAction) -> Swift.Void)? = nil, completion: (() -> Swift.Void)? = nil) { let alertController = UIAlertController(title: title, message: nil, preferredStyle: .actionSheet) alertController.addAction(UIAlertAction(title: "OK", style: .default) { (alertAction) -> Void in handler?(alertAction) }) self.present(alertController, animated: true, completion: { self.addDismissControl(alertController.view) completion?() }) } func someWhereInYourViewController() { // ... presentAlertController(title: "SomeTitle", message: "SomeMessage", preferredStyle: .actionSheet, handler: { (alertAction) -> Void in //do some action }, completion: { //do something after presentation }) // ... }