在目标视图控制器中获取 segue 的发送者

Posted

技术标签:

【中文标题】在目标视图控制器中获取 segue 的发送者【英文标题】:get sender of segue in destination view controller 【发布时间】:2013-02-04 13:08:12 【问题描述】:

我有一个名为 Dashboard (D) 的 VC,它可以打开一个名为 Login (L) 的 VC 和一个名为 Register (R) 的 VC。登录也可以打开VC注册。

我尝试尽可能多地使用故事板,所以我用它创建了三个 Segue,D 到 L、D 到 R、L 到 R

所以,在 D -> L -> R 和 D -> R 的情况下,当我关闭 R 时,我必须在必要时关闭 L 并通知 D 他可以开始加载用户信息 (简而言之,启动函数)。

所以,我想在目标 vc 中获取 Segue 的发件人,因为我知道我把它放在 performSegueWithIdentifier 的发件人条目中:

[self performSegueWithIdentifier:@"SegueToFbRegister" sender:self];

【问题讨论】:

【参考方案1】:

我会通过让 R 在注册/登录完成时发送通知来做到这一点,让 D 监听它然后弹出所有内容并加载您的数据。

如果您坚持获取对发送者的引用,您可以在目标 VC 上添加此属性,并将其设置在源 VC 的 prepareForSegue:sender:

【讨论】:

非常感谢您的快速回复,我不知道通知。我试试你的方法,这似乎更合适。但是你知道关闭 R 和 L 的最佳方式,知道 L 可能没有被创建。 您使用的是UINavigationController 吗?如果是这样,popToRootViewController: 将删除所有已推送的 VC。如果您正在呈现模态 VC,则在已呈现的第一个控制器上调用 dismissViewControllerAnimated:completion: 也会关闭所有其他已呈现在它之上的控制器。【参考方案2】:

这听起来是一个使用 Delegates 的好地方。在您的 RegisterViewController.h 中定义这样的协议

@protocol RegisterViewDelegate <NSObject>
- (void)tellRegisterDelegateSomething:(NSObject*)something;
@end

然后在你的类上保留一个指向你的委托的指针

@interface RegisterViewController : UIViewController
@property (weak, nonatomic) id <RegisterViewDelegate> delegate;
@end

现在告诉呈现的视图控制器他们实现了你刚刚创建的新协议。这是在呈现该视图的其他视图控制器的 .h 文件中完成的。

在 LoginViewController.h 中

@interface LoginViewController : UIViewController <RegisterViewDelegate>
@end

在 DashboardViewController.h 中

@interface DashboardViewController : UIViewController <RegisterViewDelegate>
@end

在上述类的.m文件中,实现协议的方法

- (void)tellRegisterDelegateSomething:(NSObject*)something


现在,当您像这样从任一呈现视图控制器执行转场时,您需要分配委托。

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

    if ([[segue identifier] isEqualToString:@"SegueToFbRegister"])
    
        RegisterViewController* destination = [segue destinationViewController];
        destination.delegate = self;
    

现在您可以调用呈现视图控制器(委托)并让它处理您需要像这样发回的任何信息(这将在您的 RegisterViewController.m 中调用)。

if ([self.delegate respondsToSelector:@selector(tellRegisterDelegateSomething:)])

    // Tell the delegate something.
    [self.delegate tellRegisterDelegateSomething:something];

您需要通过两个控制器返回的实例遵循相同的基本模式。

@protocol LoginViewDelegate <NSObject>
- (void)tellLoginDelegateSomething:(NSObject*)something;
@end

然后在你的类上保留一个指向你的委托的指针

@interface LoginViewController : UIViewController
@property (weak, nonatomic) id <LoginViewDelegate> delegate;
@end

现在告诉仪表板视图控制器它实现了协议。这是在显示此视图的仪表板视图控制器的 .h 文件中完成的。

在 DashboardViewController.h 中

@interface DashboardViewController : UIViewController <RegisterViewDelegate, LoginViewDelegate>
@end

在 DashboardViewController 的 .m 文件中实现协议的方法

在执行 segue 时,请遵循上述在视图控制器上设置委托的模式。现在,当在 LoginViewController 中调用委托方法时,您也在 DashboardViewController 中调用委托。

在 LoginViewController.m 中

- (void)tellRegisterDelegateSomething:(NSObject*)something

    if ([self.delegate respondsToSelector:@selector(tellLoginDelegateSomething:)])
    
        // Tell the delegate something.
        [self.delegate tellLoginDelegateSomething:something];
    

现在您已全部连接,因此您可以通过两个控制器(或仅一个控制器)传回数据并对其进行处理。你会知道你所处的场景,因为在 DashboardViewController 中会根据可见的 viewcontroller 调用不同的委托方法。

希望这会有所帮助。

【讨论】:

也谢谢你,但是 Taum 的解决方案对于 ios 新手来说更简单。 没问题。他的也是完全有效的。使用委托方法稍微灵活一点,因为您可以使用当前视图中的信息回调您的委托。它在您有模态视图或弹出视图的场景中也更有用,因为您可以将信息发送回委托,并且您并不总是可以选择从导航控制器中弹出这些类型的视图。绝对是一个强大的学习工具(而且不是很复杂),即使对于新手来说也是如此。祝你好运【参考方案3】:

R创建一个委托,并让DL实现委托方法。使用prepareForSegue:sender分配R。当您在 R 中完成任务时,请使用您的委托来执行所需的操作。

【讨论】:

【参考方案4】:

另一种方法是使用 unwind segue。

将以下代码放入您的 Dashboard (D) 视图控制器中。

@IBAction func loadUserInfoAfterRegistration(segue: UIStoryboardSegue) 


在 Interface Builder 中,为 Register (R) 视图控制器执行以下步骤:

    选择注册完成时按下的按钮。 Ctrl + 拖动到视图顶部的退出符号。 从显示的列表中选择loadUserInfoAfterRegistrationWithSegue:

使用这种方法,Register (R) 视图控制器将始终导航到 Dashboard (D ) 视图控制器,无论它们之间是什么。它们之间的视图控制器不必被触及。 Dashboard (D) 视图控制器中用户数据的加载也可以在上面声明的方法中自定义。

【讨论】:

以上是关于在目标视图控制器中获取 segue 的发送者的主要内容,如果未能解决你的问题,请参考以下文章

如果未关闭键盘,则在使用搜索栏时进行 segueing 会更改目标视图控制器布局

如何在 Xcode 中展开 segue

在发送者视图控制器被解雇后执行 segue

swift 4 - segue 动画完成后如何在目标视图控制器中运行代码?

嵌入 Segue 目标视图控制器被排除在 UI 状态恢复之外

自定义 Segue 在显示目标视图控制器之前动画为黑色