我得到了这个UIAlertController
,我在最顶层的视图控制器上以模态方式呈现,如下所示:
UIViewController *top = [Utility topController];
UIAlertController *alertController
= [UIAlertController alertControllerWithTitle:@"Error"
message:@"input string too long"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
}];
[alertController addAction:ok];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
}];
[alertController addAction:cancel];
[top presentViewController:alertController
animated:true
completion:nil];
}
我找到最顶层视图控制器的方法是循环显示所提供的视图控制器,并确保我不会出现在警报控制器之上:
+ (UIViewController *)topController {
UIViewController *topController = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
while (topController.presentedViewController) {
if ([topController.presentedViewController class] == [UIAlertController class]) {
[topController.presentedViewController dismissViewControllerAnimated:YES completion:nil];
break;
}
topController = topController.presentedViewController;
}
return topController;
}
这一切都很好,无论UIViewController,顶级控制器都呈现UIAlertController
,因为它是presentedViewController
。当我点击确定或取消时,UIAlertController被隐式解雇。但是,我有一个自定义UINavigationController
,它被呈现在上面,并且由于某种原因,UINavigationController也被覆盖dismissViewControllerAnimated:
被调用。
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {
[super dismissViewControllerAnimated:flag completion:completion];
}
为什么UINavigationController
有presentedViewController
被解雇,以及它自己被解雇了?我应该补充一点,我这样提出UINavigationController
:
[self presentViewController:nav animated:YES completion:nil];
为什么dismissViewControllerAnimated:
似乎被调用了两次?是否应该仅对dismissViewControllerAnimated
UINavigationController
的{{1}}调用presentedViewController
隐式调用?
答案 0 :(得分:0)
你在“顶级”代码中调用dismissViewController,这根本不对我有任何意义。
无论呈现任何UIAlertController都应该在显示警报后返回,因此在任何给定的时间点应该只有一个UIAlertController处于活动状态,因此在尝试查找最顶层的viewController以显示新的UIAlertController时无需解除之前的UIAlertController 。您不想随意解除用户的警报;你的应用需要告诉用户一些东西,所以让他们决定何时完成阅读。
建议更改:
使用类别查找当前的viewController
@implementation UIViewController (Current)
#import "UIViewController+Current.h"
@implementation UIViewController (Current)
+(UIViewController*) findBestViewController:(UIViewController*)vc {
if (vc.presentedViewController) {
// Return presented view controller
return [UIViewController findBestViewController:vc.presentedViewController];
} else if ([vc isKindOfClass:[UISplitViewController class]]) {
// Return right hand side
UISplitViewController* svc = (UISplitViewController*) vc;
if (svc.viewControllers.count > 0)
return [UIViewController findBestViewController:svc.viewControllers.lastObject];
else
return vc;
} else if ([vc isKindOfClass:[UINavigationController class]]) {
// Return top view
UINavigationController* svc = (UINavigationController*) vc;
if (svc.viewControllers.count > 0)
return [UIViewController findBestViewController:svc.topViewController];
else
return vc;
} else if ([vc isKindOfClass:[UITabBarController class]]) {
// Return visible view
UITabBarController* svc = (UITabBarController*) vc;
if (svc.viewControllers.count > 0)
return [UIViewController findBestViewController:svc.selectedViewController];
else
return vc;
} else {
// Unknown view controller type, return last child view controller
return vc;
}
}
+(UIViewController*) currentViewController {
// Find best view controller
UIViewController* viewController = [UIApplication sharedApplication].keyWindow.rootViewController;
return [UIViewController findBestViewController:viewController];
}
.h文件
#import <UIKit/UIKit.h>
@interface UIViewController (Current)
+(UIViewController*) currentViewController;
@end
然后更改“顶部”行以使用它
UIViewController *top = [UIViewController currentViewController];