You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS中UIAlert关闭后界面无响应问题求助

iOS自动登出时关闭Alert导致界面无响应的解决建议

问题场景

  • 5分钟无操作自动登出功能,无UIAlert弹窗时运行正常;
  • 存在UIAlert弹窗时,登出后弹窗会残留到登录界面;
  • 添加登出前关闭Alert的代码后,界面出现无响应,登录页输入框无法点击;
  • 仅执行关闭Alert操作,也会导致当前页面无响应。

问题根源

你当前的dismissAnyAlertControllerIfPresent方法存在两个关键问题:

  1. 顶层控制器获取逻辑错误:直接从keyWindow.rootViewController.presentedViewController开始遍历,若根VC没有presented控制器,topVC会直接为nil,后续调用dismiss会引发异常;同时嵌套弹窗场景下可能无法定位到真正的顶层Alert。
  2. UI操作未在主线程执行:自动登出逻辑大概率在子线程触发,直接调用UI操作会导致主线程混乱,引发界面无响应。

解决步骤

  1. 修正顶层VC遍历逻辑:从根VC开始完整遍历所有presented控制器,确保精准定位到顶层Alert;
  2. 强制主线程执行UI操作:所有弹窗关闭、页面跳转的UI操作必须放在主线程,避免线程冲突;
  3. 异步等待Alert关闭后跳转:利用dismiss的completion回调,确保弹窗完全关闭后再执行登录页跳转,避免UI栈混乱。

修改后的代码

- (void)dismissAnyAlertControllerIfPresentWithCompletion:(void(^)(void))completion {
    // 强制在主线程处理UI操作
    dispatch_async(dispatch_get_main_queue(), ^{
        UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
        UIViewController *currentVC = keyWindow.rootViewController;
        
        // 完整遍历所有presented控制器,找到顶层VC
        while (currentVC.presentedViewController) {
            currentVC = currentVC.presentedViewController;
        }
        
        if ([currentVC isKindOfClass:[UIAlertController class]]) {
            // 弹窗关闭完成后执行后续逻辑
            [currentVC dismissViewControllerAnimated:NO completion:completion];
        } else {
            // 无Alert直接执行回调
            if (completion) {
                completion();
            }
        }
    });
}

- (void)didLogout {
    // 先关闭Alert,完成后再执行登出逻辑和页面跳转
    [self dismissAnyAlertControllerIfPresentWithCompletion:^{
        NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
        [prefs removeObjectForKey:@"userName"];
        [prefs synchronize];
        
        [self redirectToLoginPage];
    }];
}

- (void)redirectToLoginPage {
    // 确保页面跳转在主线程执行
    dispatch_async(dispatch_get_main_queue(), ^{
        NSString *storyboardName = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone ? @"Main_iPhone" : @"Main_iPad";
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
        BmobileViewController *login = [storyboard instantiateViewControllerWithIdentifier:@"login"];
        login.hideBackbtn = YES;
        login.hideAutoLogoutMsg = YES;
        login.modalPresentationStyle = UIModalPresentationFullScreen;
        [self presentViewController:login animated:YES completion:nil];
    });
}

额外注意事项

  • 检查自动登出的触发逻辑,确保所有UI相关操作都绑定到主线程;
  • 如果登录页需要作为应用的起始页面,建议直接替换根控制器(keyWindow.rootViewController = login),避免多层present导致的UI栈冗余;
  • 测试时可添加日志打印顶层VC的类名,确认是否正确定位到Alert控制器。

内容的提问来源于stack exchange,提问作者Bhuvi c

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 15:54:59