引子
UIAlertView
在iOS9之后被Apple废弃了,Apple推荐使用UIAlertController
。但是,有时候我们使用UIAlertController
时可能不是在一个UIViewController
中,而是在一个NSObject
中,但是UIAlertController
是需要通过UIViewController
才能present
,那么如何在NSObject
中正确使用UIViewController
呢?
这里我总结了常用的三种方法。
方法一
创建一个带透明UIViewController
的UIWindow
,在此上面推出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];
}
方法二
创建一个UIAlertController
的category
,创建一个 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
方法三
创建一个UIViewController
的category
,实现一个获取当前顶部可见的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?
网友评论