iOS Modal Segue 丢弃源 ViewController?

Posted

技术标签:

【中文标题】iOS Modal Segue 丢弃源 ViewController?【英文标题】:iOS Modal Segue drops source ViewController? 【发布时间】:2012-04-10 19:34:41 【问题描述】:

在进行模态转场时,执行转场后原始 ViewController 是否会被丢弃?我正在将目标控制器的委托设置为源 ViewController,但是当目标 ViewController.viewDidLoad 时,self.delegate 为 nil...

以下代码将产生日志消息“ListViewController.viewDidLoad: My delegate is nil :(”

[来源] MapViewController:

- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    if([segue.identifier isEqualToString:@"mapToList"])
        NSLog(@"MapViewController.prepareForSegue: Segue mapToList being called, setting LisViewController's delegate to myself");
        [segue.destinationViewController setDelegate:self];
        if(!self)
            NSLog(@"MapViewController.prepareForSegue: I am nil.");
         else 
            NSLog(@"MapViewController.prepareForSegue: I am NOT nil.");
        
    

[目的地] ListViewController:

- (void)viewDidLoad

    [super viewDidLoad];

    if(!self.delegate)
        NSLog(@"ListViewController.viewDidLoad: My delegate is nil :(");
     else 
        NSLog(@"ListViewController.viewDidLoad: My delegate populated");
    

【问题讨论】:

MapViewController.prepareForSegue: Segue mapToList ... 是否出现在控制台中? 是的,抱歉,感觉这很明显。经过一些测试,特别是更改为 push segue,似乎原来的 ViewController 确实以某种方式被解雇/清除了...... 我刚刚做了一个新的应用程序,它运行良好。 See it on github. 【参考方案1】:

您的代码似乎是正确的,我唯一不同的是在我拥有的骨架框架中测试它,这是一个嵌套在导航控制器中的 tableviewcontroller。我刚刚使用以下代码进行了测试,它对我来说很好:

RootViewController .h:

@interface RootTableViewController : UITableViewController <newTest>

为 Segue 做准备(在 rootViewController 中):

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

 if ([segue.identifier isEqualToString:@"segueToModalView"])
       [segue.destinationViewController setDelegate:self];  
 

模态视图控制器.h的顶部:

@protocol newTest <NSObject>
  -(void) hello;
@end

模态视图中的属性声明:

@property (nonatomic, strong) id <newTest> delegate;

模态视图中的ViewDidLoad:

- (void)viewDidLoad

   [super viewDidLoad];
   NSLog(@"%@", self.delegate);

我的 self.delegate 的 NSLog 正确打印出来,我的代码似乎与您的代码或多或少相同。您的财产声明正确吗?

【讨论】:

所以,我认为我的问题是我的 segue 是 NavigationView 控制器,但与第二个 NavigationViewController 关联的 TableViewController 没有通过委托传递... 看看这个...这正是我的问题。当转到 secondView 并按下按钮时,它没有设置委托(我认为是由于没有从 NavigationController 传递)-github.com/wuntee/SegueTest 您在 git 项目中滥用了模式视图。模态视图被设计为与交互显示,然后返回到呈现它们的视图。它没有理由导航到导航控制器(也不应该)。如果你想做那种转场,你不应该使用模态。 我正在尝试构建的应用程序基本上有两个流程,一个在包含 Map 的 UIView 启动,另一个从 ListView 启动。关于如何获得初始状态的建议?当前设置为分段控制器通过模态segue在两个视图之间翻转... 我不完全理解您要完成的工作。我认为通过更直接的聊天会更好。您还有其他方式可以让我与您取得联系吗?【参考方案2】:

这是一个老问题,但我自己在遇到同样的问题时遇到了这个问题。这里有几件事:

    致那些不明白为什么有人会想要使用带有模态显示的导航控制器的人 - 它可以获得导航栏的好处,而不必像 tw airball 那样将 UINavigationBar 嵌入到您自己的视图控制器中。 为了解决问题而不诉诸 tw airball 确实记得在这种情况下,segue 的目标视图控制器是导航控制器...而不是嵌入在导航中的视图控制器。

所以修复就在您的 prepareForSeque 中:

UINavigationController *navController = segue.destinationViewController;
MyRealDestViewController *myRealDestViewController = (MyRealDestViewController)navController.topViewController;
myRealDestViewController.delegate = self;

【讨论】:

【参考方案3】:

如果转场是NavigationController,那么destinationViewController 将失去委托。

我通过在destinationViewController 中添加模态segue 来解决这个问题,然后添加NavigationBarBar Buttons 来模拟导航控制器(我假设您将destinationViewController 包装在NavigationController 中“完成”和“取消”按钮)。

rootViewController中设置代理正常:

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

   if ([segue.identifier isEqualToString:@"segueToModalView"])
     [segue.destinationViewController setDelegate:self];  
   

希望有帮助

【讨论】:

以上是关于iOS Modal Segue 丢弃源 ViewController?的主要内容,如果未能解决你的问题,请参考以下文章

Segue 没有被执行 ios

IOS的模态窗口(modal)

Storyboard 中的 Modal 和 Push segue 有啥区别?

使用 Modal Segue 保留复选标记

Swift、Modal Segue 和 ViewController 问题

从 Modal/Popover 展开 Segue 导致开始/结束外观转换的调用不平衡