美文网首页
在NSObject使用UIAlertController

在NSObject使用UIAlertController

作者: AprSnow | 来源:发表于2018-07-13 17:31 被阅读122次

引子

UIAlertView在iOS9之后被Apple废弃了,Apple推荐使用UIAlertController。但是,有时候我们使用UIAlertController时可能不是在一个UIViewController中,而是在一个NSObject中,但是UIAlertController是需要通过UIViewController才能present,那么如何在NSObject中正确使用UIViewController呢?
这里我总结了常用的三种方法。

方法一

创建一个带透明UIViewControllerUIWindow,在此上面推出UIAlertController。代码如下:

- (void)showAlert:(BOOL)animated {
    UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    window.rootViewController = [[UIViewController alloc] init];
    
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleAlert];
    
    [window makeKeyAndVisible];
    [window.rootViewController presentViewController:alertController animated:animated completion:nil];
}

方法二

创建一个UIAlertControllercategory,创建一个 show 方法来推出。代码如下:

#import "UIAlertController+Window.h"
#import <objc/runtime.h>

@interface UIAlertController (Window)

- (void)show;
- (void)show:(BOOL)animated;

@end

@interface UIAlertController (Private)

@property (nonatomic, strong) UIWindow *alertWindow;

@end

@implementation UIAlertController (Private)

@dynamic alertWindow;

- (void)setAlertWindow:(UIWindow *)alertWindow {
    objc_setAssociatedObject(self, @selector(alertWindow), alertWindow, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (UIWindow *)alertWindow {
    return objc_getAssociatedObject(self, @selector(alertWindow));
}

@end

@implementation UIAlertController (Window)

- (void)show {
    [self show:YES];
}

- (void)show:(BOOL)animated {
    self.alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.alertWindow.rootViewController = [[UIViewController alloc] init];

    id<UIApplicationDelegate> delegate = [UIApplication sharedApplication].delegate;
    // Applications that does not load with UIMainStoryboardFile might not have a window property:
    if ([delegate respondsToSelector:@selector(window)]) {
        // we inherit the main window's tintColor
        self.alertWindow.tintColor = delegate.window.tintColor;
    }

    // window level is above the top window (this makes the alert, if it's a sheet, show over the keyboard)
    UIWindow *topWindow = [UIApplication sharedApplication].windows.lastObject;
    self.alertWindow.windowLevel = topWindow.windowLevel + 1;

    [self.alertWindow makeKeyAndVisible];
    [self.alertWindow.rootViewController presentViewController:self animated:animated completion:nil];
}

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

    // precaution to insure window gets destroyed
    self.alertWindow.hidden = YES;
    self.alertWindow = nil;
}

@end

方法三

创建一个UIViewControllercategory,实现一个获取当前顶部可见的viewcontroller的方法,然后在上面present。代码如下:

- (UIViewController *)visibleViewControllerIfExist {
    
    if (self.presentedViewController) {
        return [self.presentedViewController visibleViewControllerIfExist];
    }
    
    if ([self isKindOfClass:[UINavigationController class]]) {
        return [((UINavigationController *)self).topViewController visibleViewControllerIfExist];
    }
    
    if ([self isKindOfClass:[UITabBarController class]]) {
        return [((UITabBarController *)self).selectedViewController visibleViewControllerIfExist];
    }
    
    if ([self isViewLoaded] && self.view.window) {
        return self;
    } else {
        NSLog(@"visibleViewControllerIfExist:,找不到可见的viewController。self = %@, self.view.window = %@", self, self.view.window);
        return nil;
    }
}

+ (UIViewController *)visibleViewController {
    UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
    UIViewController *visibleViewController = [rootViewController visibleViewControllerIfExist];
    return visibleViewController;
}

方法二来自于stackoverflow的问题How to present UIAlertController when not in a view controller?

相关文章

网友评论

      本文标题:在NSObject使用UIAlertController

      本文链接:https://www.haomeiwen.com/subject/krdspftx.html