ios 如何dismiss连续好几个viewControllers

本文探讨了iOS应用中视图控制器的返回机制问题,特别是针对连续弹出多个视图控制器后如何返回的问题。提供了两种解决方案:一是使用代理模式保持对初始视图控制器的引用;二是利用NSNotification进行通知,实现从任意层级返回。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景:我建立viewControllerA,B,C,D.目前是A presentViewController B,B presentViewController C,C presentViewController D。当想一层层地返回时,发现D dimissViewController C 可以返回。而C dismissViewController B,不可以返回了。

查了苹果官网发现: If you present several view controllers in succession, thus building a stack of presented view controllers, calling this method on a view controller lower in the stack dismisses its immediate child view controller and all view controllers above that child on the stack. When this happens, only the top-most view is dismissed in an animated fashion; any intermediate view controllers are simply removed from the stack. The top-most view is dismissed using its modal transition style, which may differ from the styles used by other view controllers lower in the stack.
大致就是如果您连续弹出几个视图控制器,从而为这些弹出的视图控制器建立一个堆栈,调用dismissViewControllerAnimated:completion:这个方法去解散其他的视图控制器。仅仅是最顶层是被解散,中间的视图控制器从栈中删除了。

解决方法:摘自网友颐和园 http://blog.youkuaiyun.com/kmyhy/article/details/7034202

一个View Controller A,弹出了一个Modal View Controller B,B又弹出了一个Modal ViewController C⋯⋯and so on。

如果你在第n个Modal View Controller的时候,想回到第一个View Controller A,或者它前面的第m个ModalView Controller C,那怎么办?

你一定想,一层层地解散呗。没错,我一开始也是这样干的:在C里解散D,在B里解散C,在A里解散B。那么你会获得一个“试图解散当前未显示的View Controller”错误。

苹果的思维非同凡响,其实你只需要解散一个Modal View Controller就可以了。即处于最底层的View Controller,这样处于这个层之上的ModalView Controller统统会被解散。

例如:你只用在A中解散B,则C、D、E、F……统统会自动被解散了。

问题在于,你在F中如何获得A? 如果是iOS 4,你可以使用parentViewController来获得当前Modal ViewController的“父View Controller”并解散自己。如果是iOS 5,你就得用presentingViewController了。

这样,你可以不停地parentViewController.parentViewController.parentViewController 下去就可以了。

代码:

if ([self respondsToSelector:@selector(presentingViewController)]) {
    [self.presentingViewController.presentingViewControllerdismissModalViewControllerAnimated:YES]; // for IOS 5+
} else {
   [self.parentViewController.parentViewControllerdismissModalViewControllerAnimated:YES]; // for pre IOS 5
}

问题是,有时候你不好确定当前Modal View Controller是链中的哪一级。比如有一个工作流,它在B处有两个分支,一个是A->B->C->D,一个是A->B->D,走哪一个分支,依赖于用户的选择。不管D或者F,处理完之后都要返回到A来进行刷新。

在D这个地方要返回A时,你不好决定要用几个parentViewController才能返回A。因为可能是3个(分支1),也可能是2个(分支2)。这样的情况下你只有用协议或者委托了。把A作为一个delegate,沿着工作流不停地传递下去,这样不管走分支1还是分支2的流程,D都始终有一个A的引用。当D的工作完成时,直接调用A实现的协议方法,在A的这个方法中解散B就可以了。


根据他的提示我使用代理来实现

第二种方法:
- (void)viewDidLoad 
{ 
	[super viewDidLoad]; // listen to any requests to dismiss all stacked view controllers 
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dismissAllViewControllers:) name:@"YourDismissAllViewControllersIdentifier" object:nil]; 
	// the remainder of viewDidLoad ...
} 
// this method gets called whenever a notification is posted to dismiss all view controllers
- (void)dismissAllViewControllers:(NSNotification *)notification // dismiss all view controllers in the navigation stack
{  
	[self dismissViewControllerAnimated:YES completion:^{}];
}

And in any other view controller down the navigation stack that decides we should return to the top of the navigation stack:

[[NSNotificationCenter defaultCenter] postNotificationName:@"YourDismissAllViewControllersIdentifier" object:self];


附:NSNotificationCenter 传递带参数的通知
NSNotificationCenter  在  init里面注册这个通知,

NSString* const str = @"FuckMe";
   [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(on:)   name:str object:nil];

在dealloc里面移除这个通知的注册: 

   [[NSNotificationCenter  defaultCenter] removeObserver:self  name:str object:nil];

以上为不带参数的通知

 

一般在使用NSNotificationCenter的时候不使用参数,但是有些时候需要使用参数。

传递参数

[[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:searchFriendArray];

接收参数并获取传递的参数

 

postNotificationName:通知的名字,也是通知的唯一标示,编译器就通过这个找到通知的。

object:传递的参数

 

- (void) test:(NSNotification*) notification

{

    searchFriendArrary = [notification object];//通过这个获取到传递的对象

} 



转载自: http://write.blog.youkuaiyun.com/postedit
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值