关于自定义 Alert

一、 window add subview

自定义 alert 的时候,没有做统一规划,都是实现一个 view,然后添加到 window 上。例如:

UIView *alert = [[UIView alloc] initWithFrame:];
[window addSubView:alert];
复制代码

这样本来也没有什么问题,有一天需求来了要支持 Voice Over,问题来了,直接盖上去的 view 不会自动聚焦,也就是手指左右滑动的时候,不能选中这个 view。而且不能 alert 出来的时候,不能自动读出。

二、利用Window 的 makeKeyAndVisible

然后想起以前 UIAlertView 显示的时候是有一个单独 window 的,于是也仿照 这样,自己建一个 window,来显示 alert,

    self.alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.alertWindow.rootViewController = [[UIViewController alloc] init];

    id<UIApplicationDelegate> delegate = [UIApplication sharedApplication].delegate;
    // Applications that does not load with UIMainStoryboardFile might not have a window property:
    if ([delegate respondsToSelector:@selector(window)]) {
        // we inherit the main window's tintColor
        self.alertWindow.tintColor = delegate.window.tintColor;
    }
    self.alertWindow.hidden = YES;
    self.frame = self.alertWindow.bounds;

    // window level is above the top window (this makes the alert, if it's a sheet, show over the keyboard)
    UIWindow *topWindow = [UIApplication sharedApplication].windows.lastObject;
    self.alertWindow.windowLevel = topWindow.windowLevel + 1;

    [self.alertWindow makeKeyAndVisible];
    [self.alertWindow addSubview:self];


    [UIView animateWithDuration:0.25 animations:^{
        self.alertWindow.hidden = NO;
    } completion:nil];

复制代码

这样显示也正常,Voice Over 也能自动聚焦,但是 手指头不小心点到空白区域的时候,还是会聚焦到下面的 view,不能只在 alert 上。 而且还有一个严重的问题 就是 自定义密码输入空间,键盘有时候不会自动弹起来,这个以前是没问题的,不知道跟这个会不会有关系。

三、presentViewController

仿照 UIAlertController 的方式,利用 presentViewController来显示提示框,这个没有上面的问题,Voice over也能自定聚焦,也不会点到下面的 view。效果还可以。

    self.mShowInViewController.definesPresentationContext = YES;
    self.mShowInViewController.providesPresentationContextTransitionStyle = YES;

    if (!self.mShowViewController) {
        UIViewController *vc = [[UIViewController alloc] init];
        vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
        UIView *backgroundView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)];
        backgroundView.backgroundColor = RGBA_COLOR_HEX(0x000000, 0.5);
        vc.backgroundView = backgroundView;
        if (self.alertType == CustomAlertTypeActionSheet) {
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onClickBackground)];
            tap.delegate = self;
            [self addGestureRecognizer:tap];
        }
        
        [vc.view addSubview:backgroundView];
        vc.view.backgroundColor = [UIColor clearColor];
//        vc.backgroundView.alpha = 0;
        self.mShowViewController = vc;
    }
}

if (!self.superview) {
        [self.mShowViewController.view addSubview:self];
    }
    self.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
    
    WEAKSELF
    [self.mShowInViewController presentViewController:self.mShowViewController animated:NO completion:^{
        [UIView animateWithDuration:0.25 animations:^{
            weak_self.mShowViewController.view.alpha = 1;
        } completion:^(BOOL finished) {
            if (complete) {
                complete(YES);
            }
        }];
    }];
复制代码

猜你喜欢

转载自juejin.im/post/5c0a51a9518825428c56fe2b