首页 文章

UIAlertController在外部点击时处理解除(IPad)

提问于
浏览
26

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

当我们使用UIActionSheet时,我们可以通过将clickedButtonAtIndex与cancelButtonIndex进行比较来轻松处理用户在弹出窗口外点击的情况(这意味着他想要取消操作) - 如果用户确实在弹出窗口外按下了取消按钮索引在这个功能 .

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

3 回答

  • 43

    您可以使用样式添加动作:UIAlertActionStyleCancel,当用户点击弹出窗口外,将调用此动作的处理程序 .

    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];
    }
    
  • 16

    适用于UIAlertController并具有警报风格的解决方案 . 只需要为alertController superview添加手势识别器 .

    [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];
    }
    
  • 1

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

相关问题