6

我的问题是,如何让以下自定义展开转场在 iOS 9 之前版本的设备以及运行 iOS 9 的设备上工作?

我有一个显示视图控制器的自定义 Segue,然后有一个相应的自定义展开 Segue。此代码在 iOS 8 中运行良好,通过创建 UIStoryboardSegue 的子类并实现该perform方法来实现。然后我在我的自定义导航控制器中覆盖以下方法:

- (UIStoryboardSegue *) segueForUnwindingToViewController:    (UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
{
    UIStoryboardSegue *segue;
    if([fromViewController isKindOfClass:[MyViewController class]]){
        segue = [[CustomSegue alloc] initWithIdentifier:identifier source:fromViewController destination:toViewController]; //Custom Unwind Segue
    }
    else{
        UIStoryboardSegue *unwindSegue = [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier]; //Normal Unwind Segue
        segue = unwindSegue;
    }
    return segue;
}

在 iOS 9 中,segueForUnwindingToViewController已弃用。它仍然适用于 MyViewController CustomSegue;但是,默认展开转场不再适用于任何其他展开转场。尽管在 super 上调用该方法会返回一个 unwind segue,但 segue 永远不会发生,视图控制器永远不会弹出,并且用户永远无法返回上一个屏幕。所以要明确一点,如果我使用常规的 show segue,则相应的 unwind segue 会调用已弃用的方法,该方法会调用 super 上的方法,并且不起作用。

我观看了故事板上的 WWDC 演讲,我能够通过以下方式在 iOS 9 中解决此问题:a)不再在我的自定义导航控制器中覆盖此方法,b)进入故事板,单击自定义 segue,然后输入CustomSegue作为 Segue 类。不幸的是,由于我的目标是 iOS 7,我收到警告“只有自定义 segues 支持 iOS 9 之前的类名”,并且自定义展开 segue 现在不适用于 iOS 7 或 iOS 8!

4

2 回答 2

3

经过大量的试验和错误,我找到了一种解决方法。我注意到,当您覆盖时segueForUnwindingToViewControllerunwindForSegue:towardsViewController不再调用,这就是问题所在。仅供参考,Apple 在 UIViewController 中的注释segueForUnwindingToViewController说:

已弃用。返回一个 segue,它将通过该unwindForSegue:towardViewController:方法从源视图控制器展开到目标视图控制器。在执行故事板中定义的展开转场时,如果展开路径上的任何视图控制器已覆盖此方法并返回非零,则运行时将使用该转场对象而不是构造接口生成器中指定的类的实例。

粗体部分的语句似乎没有被实现,即如果你重写这个方法但返回 nil,unwindForSegue:towardViewController仍然没有被调用并且 segue 不会发生。

为了解决这个问题,我可以segueForUnwindingToViewController在我的自定义导航控制器中编辑:

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
{
    UIStoryboardSegue *segue;
    if([fromViewController isKindOfClass:[MyViewController class]]){
        segue = [[CustomSegue alloc] initWithIdentifier:identifier source:fromViewController destination:toViewController]; //Custom Unwind Segue
    }
    else{
        if([[UIDevice currentDevice].systemVersion floatValue] < 9.0){
            return [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier]; //Normal Unwind Segue
        }
        else{
            [super unwindForSegue:segue towardsViewController:toViewController];
            return nil;
        }
    }
    return segue;
}

更新:调用[super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];似乎仍然适用于模态展开segues。我描述的问题似乎发生在秀场上。因此,如果您的设备在版本 < 9.0 上运行,或者如果 segue 是模态的,您仍然应该调用旧方法。如果您[super unwindForSegue:segue towardsViewController:toViewController];在 segue 处于模态时调用,则 segue 将不起作用/发生。

于 2015-09-24T04:42:02.250 回答
1

我稍微修改了你的代码。
我不必考虑是推送还是模态。
它似乎工作正常。

- (UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(NSString *)identifier
{
    UIStoryboardSegue *segue;
    if ([fromViewController isKindOfClass:[MyViewController class]]) {
        segue = [[CustomSegue alloc] initWithIdentifier:identifier source:fromViewController destination:toViewController]; //Custom Unwind Segue
    }
    else {
        if ([super respondsToSelector:@selector(unwindForSegue:towardsViewController:)]) {
            [super unwindForSegue:segue towardsViewController:toViewController];
        }
        segue = [super segueForUnwindingToViewController:toViewController fromViewController:fromViewController identifier:identifier];
    }

    return segue;
}
于 2015-09-28T05:00:43.607 回答