Objective-C:Segue返回时重复创建ViewController如何解决?
问题:Segue返回时重复创建视图控制器实例
我有两个视图控制器:
- ViewController
- TableViewController
当我在TableViewController中通过Segue返回上一个视图时,它始终会创建一个新的ViewController副本。我需要Segue返回之前的视图,而非重复创建实例。

当前TableViewController.m的代码如下:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { NSString *identifire = [sender text]; ViewController* vc = (ViewController*)segue.destinationViewController; [vc view]; [vc hideElements:identifire]; }
解决方案
嘿,这个问题我太熟了!你现在踩的是Segue的一个常见误区——默认的push/modal类型Segue,本来就是用来创建新的视图控制器实例并加入导航栈的,根本不是用来返回上一个页面的。要回到之前的ViewController实例,得换个思路:
方法1:直接返回(不需要传数据)
如果你只是想回到上一页,完全不需要用Segue,直接在TableViewController里调用导航控制器的返回方法就行:
[self.navigationController popViewControllerAnimated:YES];
这个方法会直接把当前控制器从导航栈里移除,回到栈里原来的那个ViewController实例,绝对不会创建新副本。
方法2:需要传递数据再返回
如果你还需要像之前那样把identifire传递给原来的ViewController,那可以用代理模式来实现,步骤很简单:
第一步:给TableViewController定义代理协议
在TableViewController.h里添加协议:
@protocol TableViewControllerDelegate <NSObject> - (void)tableViewController:(TableViewController *)vc didSelectIdentifier:(NSString *)identifier; @end @interface TableViewController : UITableViewController @property (nonatomic, weak) id<TableViewControllerDelegate> delegate; @end
第二步:在ViewController里实现代理
当ViewController跳转到TableViewController的时候,把自己设为代理:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // 记得替换成你实际的Segue标识符 if ([segue.identifier isEqualToString:@"ToTableVC"]) { TableViewController *tableVC = segue.destinationViewController; tableVC.delegate = self; } } // 实现代理方法,接收数据并处理 - (void)tableViewController:(TableViewController *)vc didSelectIdentifier:(NSString *)identifier { [self hideElements:identifier]; // 处理完数据后返回上一页 [self.navigationController popViewControllerAnimated:YES]; }
第三步:在TableViewController里触发代理
把原来触发Segue的逻辑,改成调用代理方法就行(比如你是点击cell触发的话):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath]; NSString *identifier = selectedCell.textLabel.text; // 调用代理方法传递数据 [self.delegate tableViewController:self didSelectIdentifier:identifier]; }
这样操作下来,既能把数据传给原来的ViewController,又能回到之前的实例,完全不会创建新的副本啦!
内容的提问来源于stack exchange,提问作者Eli
相关产品推荐
相关产品推荐

