自定义 UIStoryboardSegue 使用 segueWithIdentifier:source:destination:performHandler:

Posted

技术标签:

【中文标题】自定义 UIStoryboardSegue 使用 segueWithIdentifier:source:destination:performHandler:【英文标题】:Custom UIStoryboardSegue using segueWithIdentifier:source:destination:performHandler: 【发布时间】:2013-11-22 10:57:30 【问题描述】:

我正在尝试使用自定义UIStoryboardSegue 来实现两个视图控制器之间的转换。我可以通过子类化UIStoryboardSegue 来做到这一点,然后在 IB 中设置这个类。但是,我正在查看文档说:

如果您的 segue 不需要存储其他信息或提供除 perform 方法之外的任何内容,请考虑改用 segueWithIdentifier:source:destination:performHandler: 方法。

表示不需要创建自定义子类,使用自定义performHandler即可。

我对这段代码应该去哪里以及如何使用它感到困惑。我是否像往常一样在 IB 中创建 segue,然后在它被触发之前覆盖它(可能在 shouldPerformSegue: 或类似中)。在苹果文档的其他地方,它说:

您的应用从不直接创建 segue 对象;它们总是在触发 segue 时由 ios 代表您创建

所以我不太明白他们为什么说要使用类创建器方法实例化一个 segue。

【问题讨论】:

【参考方案1】:

segueWithIdentifier:source:destination:performHandler:的点

在您还想创建自定义过渡而不创建 segue 子类的情况下,提供 UIViewController performSegueWithIdentifier:sender 的替代方案。 提供一个可用作segueForUnwindingToViewController:fromViewController:identifier 回报的segue

如上所述,这种方法仅适用于您手动调用的 segue,即不适用于通过 IB 触发器触发的 segue。

因此,例如,如果您有一个 segue 需要在某个超时时间后触发(例如自定义锁屏),您可以使用 segueWithIdentifier:source:destination:performHandler: 来处理自定义转换。

-(void)appTimeoutLockScreen

    UIStoryboardSegue *segue = 
                [UIStoryboardSegue segueWithIdentifier:@"LockScreenSegue" 
                                                source:sourceVC 
                                           destination:destinationVC 
                                        performHandler:^
                     // transition code that would 
                     // normally go in the perform method
                ];
    // Dev is responsible for calling prepareForSegue and perform.
    // Note, the order of calls for an IB triggered segue as well as
    // a performSegueWithIdentifier segue is perform first, then
    // prepareForSegue:sender. Manual segues need to inverse the call
    // in order to ensure VC setup is finished before transition.
    [self prepareForSegue:segue sender:self];
    [segue perform];

该方法的另一个实际用途是展开segue。使用类似的场景 对于上一个示例,我们可以使用它返回一个 segue 以从锁定屏幕转换回之前的 viewController:

-(UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController*)toVC 
                                     fromViewController:(UIViewController *)fmVC
                                             identifier:(NSString *)identifier

    UIStoryboardSegue *segue = 
            [UIStoryboardSegue segueWithIdentifier:@"FromLockScreenSegue" 
                                            source:fmVC
                                       destination:toVC 
                                    performHandler:^
                // transition code
            ];

    return segue;

【讨论】:

问题是:你在哪里称呼segueWithIdentifier:source:destination:performHandler:?它(大概)返回UIStoryboardSegue 的(子类),但是然后呢?没有采用UIStoryboardSegue 实例的performSegue: 方法,只是一个segue 的标识符。 你可以在使用 unwindingSegue 时使用它。您可以将它用于 -(UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier 的返回对象,但问题仍然是您将在何处或如何将其用于“前进”移动segues。 我已经更新了示例代码。调用类方法自动触发segue,无需调用performSegueWithIdentifier:sender。或者更具体地说,如果您还希望进行自定义转换,则它是调用 performSegueWithIdentifier:sender 的一种替代方法 @MichaelG.Emmons 我一定是做错了什么,因为我遵循了您提供的示例代码,但处理程序从未执行。我在那里输入了一个日志以确保没有任何反应。 @daveMac 我有一个我不久前创建的演示应用程序,它可以做到这一点。我会看看。不过,我还需要几个小时才能完成。

以上是关于自定义 UIStoryboardSegue 使用 segueWithIdentifier:source:destination:performHandler:的主要内容,如果未能解决你的问题,请参考以下文章

自定义 UIStoryboardSegue 和 UIViewController 转换之间的区别

UIStoryboardSegue:动画期间不显示视图

UIStoryBoardSegue 过渡 - 状态栏问题

UIStoryboardSegue & UIVisualEffectView - 完成块退出后模糊效果丢失

为什么在自定义交叉溶解segue中视图控制器的主视图不对齐?

使用自定义转场执行自定义转换的正确方法 - 没有副作用