前言
使用 UIAlertController 弹出对话框时,想支持用户点击空白处能自动隐藏对话框。UIAlertControllerStyleActionSheet添加cancel按钮即可实现。同样的,UIAlertControllerStyleAlert即使添加cancel按钮也不行,下面,我们使用分类给它添加自动隐藏功能。
UIAlertController+HLTapDismiss.h
#import <UIKit/UIKit.h>
@interface UIAlertController (HLTapDismiss)
/// 弹窗点击dismiss
- (void)alertTapDismiss;
@end
UIAlertController+HLTapDismiss.m
#import "UIAlertController+HLTapDismiss.h"
@interface UIAlertController ()<UIGestureRecognizerDelegate>
@end
@implementation UIAlertController (HLTapDismiss)
- (void)alertTapDismiss {
NSArray * arrayViews = [UIApplication sharedApplication].keyWindow.subviews;
if (arrayViews.count>0) {
//array会有两个对象,一个是UILayoutContainerView,另外一个是UITransitionView,我们找到最后一个
UIView * backView = arrayViews.lastObject;
backView.userInteractionEnabled = YES;
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap)];
tap.delegate = self;
[backView addGestureRecognizer:tap];
}
}
- (void)tap {
[self dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
UIView *tapView = gestureRecognizer.view;
CGPoint point = [touch locationInView:tapView];
CGPoint conPoint = [self.view convertPoint:point fromView:tapView];
BOOL isContains = CGRectContainsPoint(self.view.bounds, conPoint);
if (isContains) {
// 单击点包含在alert区域内 不响应tap手势
return NO;
}
return YES;
}
@end
栗子
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"测试" message:@"测试一下" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"取消");
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"sure" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"确定");
}]];
[self presentViewController:alert animated:YES completion:^{
// 添加点击空白隐藏手势
[alert alertTapDismiss];
}];