不同方法present自定义UIViewController后dismiss无效果如何解决?
问题排查及解决方法
- 重复创建控制器导致dismiss对象不匹配
你当前的present方法每次调用都会创建新的UIViewController实例并覆盖self.customView的原有赋值,如果你多次触发了present逻辑,界面上显示的是旧实例,dismiss时操作的是从未被present过的新实例,就会出现回调正常执行但界面无变化的情况,系统也不会抛出报错。
修复后的present代码:-(void)presentViewController { // 已存在实例则直接返回,避免重复创建 if (_customView) return; self.customView = [[UIViewController alloc] init]; [self.customView setModalPresentationStyle: UIModalPresentationOverFullScreen]; [self presentViewController:self.customView animated:YES completion:nil]; } - dismiss调用主体错误
模态跳转的正确逻辑是「谁present谁负责dismiss」,直接调用被弹出的控制器的dismiss方法虽然系统会自动转发给presentingViewController,但如果层级嵌套复杂就可能出现转发失效的问题。建议统一由presentingViewController执行dismiss操作,同时dismiss完成后清空属性避免内存泄漏:
修复后的dismiss代码:
如果你是在customView内部的按钮触发关闭,直接在customView的按钮回调里执行以下代码即可:-(void)dismissViewController { dispatch_async(dispatch_get_main_queue(), ^{ if (self.customView.presentingViewController) { [self.customView.presentingViewController dismissViewControllerAnimated:YES completion:^{ self.customView = nil; }]; } }); }- (void)closeButtonClick:(UIButton *)sender { dispatch_async(dispatch_get_main_queue(), ^{ [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; }); } - UI操作未在主线程执行
如果你的dismiss方法是在子线程中被触发,UI更新不会生效,且系统大概率不会打印报错。上面的代码已经增加了主队列调度逻辑,可直接复用。 - 其他排查方向
你可以用Xcode的「Debug View Hierarchy」工具查看当前视图层级,确认是否有其他层级更高的自定义View盖住了当前的customView,导致你误以为dismiss没有生效。另外建议你把属性名customView改为customViewController,避免类型歧义引发后续维护问题。
内容的提问来源于stack exchange,提问作者Baxter
相关产品推荐
相关产品推荐

