能否不借助第三方库修改UIAlertController的背景颜色?附尝试代码
不借助第三方库修改UIAlertController背景颜色的可行方案
嘿,没问题,不依赖第三方库确实能实现这个需求!不过得先提醒你:UIAlertController的视图层级在不同iOS版本里会有变化,你之前硬编码子视图索引的方式(比如firstSubview.subviews.firstObject)很容易在系统更新后失效,而且直接操作未公开的视图结构存在一定的App Store审核风险,使用前一定要在目标版本上充分测试。
为什么你的代码没生效?
你是在present alert之前就尝试修改子视图,但此时alert的视图还没完成布局,很多子视图都还没被创建出来,所以修改自然不会生效——得等alert被成功展示后再动手。
两种可行的实现方法
方法1:递归查找目标背景视图(相对安全)
通过递归遍历alert的视图树,定位到默认的白色背景容器,这种方式不依赖私有属性,兼容性相对更好:
// 先写个递归查找的辅助方法 - (UIView *)locateAlertBackgroundView:(UIView *)parentView { // 先判断当前视图是不是我们要找的背景容器(默认是白色,可根据实际情况调整) if (parentView.backgroundColor && [parentView.backgroundColor isEqual:[UIColor whiteColor]]) { // 进一步验证:这个视图应该包含标题、消息和按钮的子容器 if (parentView.subviews.count >= 2) { return parentView; } } // 递归遍历所有子视图 for (UIView *subview in parentView.subviews) { UIView *targetView = [self locateAlertBackgroundView:subview]; if (targetView) { return targetView; } } return nil; } // 实际调用代码 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert]; // 配置按钮和文字颜色 UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil]; UIAlertAction *deleteAction = [UIAlertAction actionWithTitle:@"Delete" style:UIAlertActionStyleDefault handler:nil]; [cancelAction setValue:[UIColor greenColor] forKey:@"titleTextColor"]; [deleteAction setValue:[UIColor redColor] forKey:@"titleTextColor"]; [alert addAction:cancelAction]; [alert addAction:deleteAction]; // 在present完成的回调里修改背景色 [self presentViewController:alert animated:YES completion:^{ UIView *bgView = [self locateAlertBackgroundView:alert.view]; if (bgView) { bgView.backgroundColor = [UIColor colorWithRed:255/255.0f green:255/255.0f blue:255/255.0f alpha:1.0f]; // 要是想调整圆角,还能加这句 bgView.layer.cornerRadius = 12; // 数值按需调整 } }];
方法2:用KVC访问私有属性(更直接但有风险)
如果你能接受私有API的风险(可能导致审核被拒或后续版本崩溃),可以直接通过KVC访问UIAlertController的私有视图属性,这种方式更简洁:
[self presentViewController:alert animated:YES completion:^{ // 获取alert的主容器视图 UIView *alertContainerView = [alert valueForKey:@"_alertControllerView"]; // 获取内部的内容容器 UIView *contentView = [alertContainerView valueForKey:@"_contentView"]; if (contentView) { contentView.backgroundColor = [UIColor colorWithRed:255/255.0f green:255/255.0f blue:255/255.0f alpha:1.0f]; } }];
关键注意事项
- 版本测试:UIAlertController的视图结构在iOS 13、15等版本都有过调整,所以无论用哪种方法,都要在你需要支持的iOS版本上反复测试。
- 审核风险:方法2里的
_alertControllerView和_contentView都是私有属性,Apple不允许在提交到App Store的应用里使用这类未公开API,所以如果是面向公开发布的应用,更推荐用方法1。
内容的提问来源于stack exchange,提问作者iPhone Programmatically
相关产品推荐
相关产品推荐

