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

iOS 8+中UITabBarVC上层透明ViewController显示异常求助

解决UITabBarController Present半透明视图控制器后背景变不透明的问题

这个问题我之前也碰到过!核心原因是你用的UIModalPresentationCurrentContext在UITabBarController的场景下有层级限制:当动画结束后,UITabBarController的tabBar会影响模态视图的最终渲染层级,导致你的半透明背景被底层的不透明内容(比如tabBar的背景)覆盖,看起来就变成了不透明的深色调。

最优解决方案

改用UIModalPresentationOverFullScreen(iOS 8及以上支持),这个模态样式会让你的透明视图直接覆盖在整个屏幕的最上层,完全不受UITabBarController的视图层级影响,能完美保持半透明效果。

修改后的Objective-C代码

- (void)showBusyWithCompletion:(void (^)(BOOL))completion {
    UIViewController *vc = [[UIViewController alloc] init];
    vc.view.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.5];
    vc.view.opaque = NO;
    // 替换为OverFullScreen样式
    vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
    [self presentViewController:vc animated:YES completion:^{
        [self performSelector:@selector(hideBusy:) withObject:vc afterDelay:4];
        if (completion) {
            completion(YES);
        }
    }];
}

- (void)hideBusy:(UIViewController *)vc {
    [self dismissViewControllerAnimated:YES completion:nil];
}

额外提供Swift版本参考

func showBusy(completion: ((Bool) -> Void)? = nil) {
    let vc = UIViewController()
    vc.view.backgroundColor = UIColor.red.withAlphaComponent(0.5)
    vc.view.isOpaque = false
    vc.modalPresentationStyle = .overFullScreen
    
    present(vc, animated: true) {
        completion?(true)
        DispatchQueue.main.asyncAfter(deadline: .now() + 4) {
            self.hideBusy(vc: vc)
        }
    }
}

func hideBusy(vc: UIViewController) {
    vc.dismiss(animated: true)
}

补充说明

如果你的项目需要兼容iOS 7及以下(现在几乎很少见了),可以换一种思路:直接在UITabBarController的view上添加一个半透明的遮罩视图,而不是present新的控制器,也能实现相同的效果。不过UIModalPresentationOverFullScreen是更符合现代iOS开发规范的优雅方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:49:31