美文网首页
在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