Objective-C中如何实现从一个弹窗触发弹出另一个弹窗
你当前调用的[weakself.navigationController pushViewController:deleteVC animated:YES];无法实现弹窗效果的核心原因是:UINavigationController的push逻辑是往导航栈内追加页面,默认触发全屏推入转场,和模态弹窗的呈现逻辑完全独立。只要你调用的是外层页面绑定的全局导航控制器push,不管当前触发操作的页面是不是弹窗,都会跳全屏新页面。
完全可以通过UINavigationController实现弹窗嵌套弹出的效果,核心是不要复用外层全屏页面的导航控制器,给弹窗容器单独配置专属导航栈即可,以下是可直接落地的实现方案:
方案1:无导航需求直接模态弹出(最简单)
如果第二个弹出的deleteVC不需要导航栏、也没有后续栈内跳转需求,直接在当前弹窗控制器上用模态方式呈现即可,提前设置非全屏的模态样式就不会跳全屏页面:
// 按你需要的弹窗尺寸选择对应样式,自定义弹窗就选Custom deleteVC.modalPresentationStyle = UIModalPresentationFormSheet; // 自定义转场的话在这里绑定transitioningDelegate即可 [weakself presentViewController:deleteVC animated:YES completion:nil];
如果弹窗内部需要导航栏、后续还要在弹窗范围内做页面切换(比如多步表单弹窗),按以下逻辑实现即可:
- 弹出第一个弹窗时,不要直接弹出弹窗控制器本身,先创建一个UINavigationController实例,把第一个弹窗设为这个导航控制器的根控制器
- 给这个导航控制器设置非全屏的模态样式,用模态方式弹出这个导航控制器
- 后续要在弹窗内唤起第二个弹窗/页面时,直接调用弹窗自身绑定的导航控制器push,所有转场都会局限在弹窗的容器范围内,不会触发外层全屏跳转
示例代码:
// 弹出第一个弹窗的代码,给弹窗嵌专属导航 FirstPopupVC *firstPopup = [[FirstPopupVC alloc] init]; UINavigationController *popupNav = [[UINavigationController alloc] initWithRootViewController:firstPopup]; // 设为非全屏弹窗样式,要浮层透传效果可以选UIModalPresentationOverCurrentContext popupNav.modalPresentationStyle = UIModalPresentationFormSheet; [self presentViewController:popupNav animated:YES completion:nil]; // 第一个弹窗内部唤起第二个页面/弹窗的代码 // 这里self指FirstPopupVC实例,拿到的是弹窗专属的导航控制器,不是外层全局导航 DeleteVC *deleteVC = [[DeleteVC alloc] init]; [self.navigationController pushViewController:deleteVC animated:YES];
避坑提醒
- 绝对不要拿外层页面的导航控制器调用push,这个控制器管的是全屏页面栈,必然触发全屏跳转
- 只要承载弹窗的导航控制器本身是非全屏模态呈现的,它内部push/pop的所有页面都会被限制在弹窗的显示区域内,天然实现弹窗内的层叠跳转效果
- 如果需要弹窗半透明遮罩效果,把modalPresentationStyle改成
UIModalPresentationOverFullScreen即可,不会清空下层页面的渲染内容
内容的提问来源于stack exchange,提问作者Man Kit Tsui
相关产品推荐
相关产品推荐

