关闭 UIAlertController 时调用 UINavigation 的 dismissViewControllerAnimated 方法

Posted

技术标签:

【中文标题】关闭 UIAlertController 时调用 UINavigation 的 dismissViewControllerAnimated 方法【英文标题】:UINavigation's dismissViewControllerAnimated method called when closing UIAlertController 【发布时间】:2017-04-05 17:17:06 【问题描述】:

我在理解 ios 视图控制器和警报控制器在特定情况下如何工作时遇到了问题:

我有一个自定义UINavigationController,其中有我的UIViewController。我的导航控制器已覆盖 dismissViewControllerAnimated:completion 方法。从这个UIViewController 我提出新的UIAlertController。在用户单击警报中的任何按钮之前,一切正常。然而,奇怪的是,我的自定义 UINavigationController 的 dismissViewControllerAnimated:completion 方法正在被调用(如果可能的话,我不希望那样......)

警报以常规方式呈现(来自 UINavigationController 中的 UIViewController):

UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"yep" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) 
    [self takeOrder:data];
];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"nope" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) 

];

[confirmOrderAcceptAlert addAction:okAction];
[confirmOrderAcceptAlert addAction:cancelAction];

[self presentViewController:alert animated:YES completion:nil];

是否有任何选项可以防止这种行为?为什么会发生这种情况?

编辑: dismissViewControllerAnimated:completion的代码:

- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion 
    self.isHeroEnabled = NO;
    [super dismissViewControllerAnimated:flag completion:completion];

我正在使用Hero 库来制作过渡动画,是这样吗?

【问题讨论】:

请在您的自定义导航控制器中显示dismissViewControllerAnimated:completion的代码 感谢回复,问题已编辑 【参考方案1】:

当你继承 UINavigationController 时,它肯定会调用dismissViewControllerAnimated:completion。

为避免它干扰库代码,请检查特定的 ViewController 类型。

例如:

- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion 
    if(![self.visibleViewController isKindOfClass:[UIAlertController class]])
            self.isHeroEnabled = NO;
    
    [super dismissViewControllerAnimated:flag completion:completion];

【讨论】:

谢谢 :) 看来它正在工作。但是,我不明白为什么要调用此方法。我知道,“这就是它在 ios 中的工作方式”但是为什么? :) 好的!告诉我你为什么首先创建一个子类?要求是什么? :O 答案是当您想要访问所有子类共有的方法或在父类中设置一个值时,该值将反映在所有子类中。在您的情况下,Hero 库可能会设置一些 iVar 来识别演示视图控制器或弹出视图控制器(不确定值 isHeroenabled)。 ;) 而它之所以调用这个方法,是因为alertviewcontroller被解除了。苹果库会调用dismissviewcontroller方法,当你点击任意一个alertview按钮时,会调用uinavigationcontroller这个方法。 当然,赞成!我将导航控制器子类化,因为我需要控制启用/禁用后退按钮/滑动。另外,它是一种遗留代码,所以它已经存在了 :) 好的,感谢您的解释,仍在学习新东西 :)【参考方案2】:

UINavigationController 就是这样工作的

如果您不想为由于警报而调用的操作设置 HeroEnabled。你可能需要做类似的事情

if(![self.visibleViewController isKindOfClass:[UIAlertController class]]) self.isHeroEnabled = NO

【讨论】:

以上是关于关闭 UIAlertController 时调用 UINavigation 的 dismissViewControllerAnimated 方法的主要内容,如果未能解决你的问题,请参考以下文章

不要关闭 UIAlertController

仪器关闭时调用缓慢

我不断收到此错误:“阅读器关闭时调用读取无效”

为啥在 UINavigationController 上关闭 UIAlertController 调用关闭?

如何在尝试使用资源时调用方法[关闭]

如何在选项卡/浏览器关闭时调用 .NET MVC 操作?