You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

不同方法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代码:
    -(void)dismissViewController {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (self.customView.presentingViewController) {
                [self.customView.presentingViewController dismissViewControllerAnimated:YES completion:^{
                    self.customView = nil;
                }];
            }
        });
    }
    
    如果你是在customView内部的按钮触发关闭,直接在customView的按钮回调里执行以下代码即可:
    - (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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 18:18:03