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

如何在不进行大量重构的前提下移除代码中废弃的UIAlertView?

第三种可行解决方案

可以通过给UIAlertController添加Objective-C分类(Category)的方式,封装和旧版UIAlertView一致的show方法,内部自动获取当前应用最顶层的视图控制器来执行present逻辑,既不需要大量重构现有业务代码,也不用每次手动获取VC。

分类实现代码

头文件 UIAlertController+Show.h

#import <UIKit/UIKit.h>

@interface UIAlertController (Show)
/// 直接弹出当前弹窗,用法和旧版UIAlertView的show完全一致
- (void)show;
/// 快速弹出只有确认按钮的普通提示弹窗
+ (void)showAlertWithTitle:(NSString *)title message:(NSString *)message confirmTitle:(NSString *)confirmTitle;
@end

实现文件 UIAlertController+Show.m

#import "UIAlertController+Show.h"

@implementation UIAlertController (Show)

// 内部工具方法:获取当前应用最顶层的可present视图控制器
+ (UIViewController *)topmostViewController {
    UIViewController *topVC = [[[UIApplication sharedApplication] delegate] window].rootViewController;
    while (topVC.presentedViewController) {
        // 跳过正在销毁的控制器,避免present报错
        if (topVC.presentedViewController.isBeingDismissed) break;
        // 适配容器控制器
        if ([topVC.presentedViewController isKindOfClass:[UINavigationController class]]) {
            topVC = [(UINavigationController *)topVC.presentedViewController topViewController];
        } else if ([topVC.presentedViewController isKindOfClass:[UITabBarController class]]) {
            topVC = [(UITabBarController *)topVC.presentedViewController selectedViewController];
        } else {
            topVC = topVC.presentedViewController;
        }
    }
    return topVC;
}

- (void)show {
    [[UIAlertController topmostViewController] presentViewController:self animated:YES completion:nil];
}

+ (void)showAlertWithTitle:(NSString *)title message:(NSString *)message confirmTitle:(NSString *)confirmTitle {
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    [alert addAction:[UIAlertAction actionWithTitle:confirmTitle style:UIAlertActionStyleDefault handler:nil]];
    [alert show];
}

@end

改造后用法

原有旧代码:

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"操作成功" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
[alert show];

替换后仅需修改少量代码,不需要调整业务上下文:

UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"操作成功" preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil]];
[alert show];

简单提示弹窗甚至可以用一行代码完成:

[UIAlertController showAlertWithTitle:@"提示" message:@"操作成功" confirmTitle:@"确定"];
苹果废弃UIAlertView的原因
  • 设计规范统一:UIAlertView是UIView子类,独立于UIKit的视图控制器体系之外,直接挂载到系统window上,不符合MVC设计规范,视图的展示逻辑不归属于对应的视图控制器管控。而UIAlertController完全遵循视图控制器的管理规则,所有转场、层级、生命周期都和普通VC一致,降低系统维护成本。
  • 解决历史遗留问题:UIAlertView存在大量已知问题,比如横竖屏旋转适配异常、和其他自定义弹窗/系统弹窗的层级冲突、代理回调容易产生野指针崩溃、无法自定义弹窗内容和动画效果等,这些问题在旧的实现框架下很难彻底修复。
  • API复用性提升:UIAlertController同时支持弹窗(Alert)和底部操作表(ActionSheet)两种样式,只需要修改preferredStyle参数即可切换,不需要再维护UIAlertView和UIActionSheet两套完全独立的API,降低开发者的学习成本和系统的维护成本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 01:09:04