UIAlertView 清理根视图

UIAlertView cleaning Root View

我有一个 UIAlertView,它在按钮上调用一个方法来添加类似视图的弹出窗口。

代码如下:

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    [IAPHelper addPurchasePopupWithDelegate: self];
}

该方法addPurchasePopupWithDelegate将从XIB加载的UIView添加到根视图,获取如下:

UIWindow *window = [UIApplication sharedApplication].keyWindow;
UIView *rootView = window.rootViewController.view;
...

我不想做的不同的事情:

问题是我的视图出现后几乎立即消失。原因是当 iOS 将关闭 UIAlertView 时,它会以某种方式清理 window.rootViewController.view

以下方法有效:

-(void) callIAP {
    [IAPHelper addPurchasePopupWithDelegate: self];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    [self performSelector:@selector(callIAP) withObject: self afterDelay:0.5];
}

但我认为这不是一个可以接受的解决方案。 问题是,如何在 UIAlertView 按钮回调中向根视图添加视图?

一切都在主线程中执行。

首先,我确认在iOS8中存在问题。任何人都可以通过 运行 来自视图控制器的代码块

来简单地验证它
@interface ViewController ()<UIAlertViewDelegate>    
@end

@implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    // Show alert
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Notice" message:@"Adding a view to the root view..." delegate:self cancelButtonTitle:nil otherButtonTitles:@"Now!", nil];
    [alert show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    UIView *dummyView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 80, 80)];
    dummyView.backgroundColor = [UIColor redColor];

    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    UIView *rootView = window.rootViewController.view;

    [rootView addSubview:dummyView];
}
@end

但是等一下...有必要UIAlertView吗?从 iOS 8 UIAlertView 开始弃用。这是来自 UIAlertView class reference:

的内容

Important: UIAlertView is deprecated in iOS 8. (Note that UIAlertViewDelegate is also deprecated.) To create and manage alerts in iOS 8 and later, instead use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert.

切换到 UIAlertController 上面的代码块将如下所示:

@interface ViewController ()
@end

@implementation ViewController

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    // Show alert immediately
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Notice" message:@"Adding a view to the root view..." preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *addAction = [UIAlertAction actionWithTitle:@"Now!" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        [self addDummyView];
    }];
    [alert addAction:addAction];
    [self presentViewController:alert animated:YES completion:nil];
}

- (void)addDummyView {
    UIView *dummyView = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 80, 80)];
    dummyView.backgroundColor = [UIColor redColor];

    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    UIView *rootView = window.rootViewController.view;

    [rootView addSubview:dummyView];
}

@end

它只是 有效

总而言之,如果某些东西被标记为deprecated,没有特殊原因不要试图坚持下去。请改用 Apple 建议的内容。

编码愉快!