为iOS 8和iOS 9定制反向转场的方法

6
我的问题是,如何使以下自定义反向转场在iOS 9之前的设备以及运行iOS 9的设备上正常工作?
我有一个自定义转场显示一个视图控制器,然后有一个相应的自定义反向转场。这段代码在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上调用该方法会返回一个返回动作,但是该返回动作永远不会发生,视图控制器也不会弹出,用户无法返回到前一个屏幕。所以为了明确,如果我使用常规的show segue,相应的返回动作将调用弃用的方法,该方法将调用super上的方法,并且不起作用。
我观看了关于storyboards的WWDC演讲,并且能够通过以下方式解决这个问题:a)不再覆盖自定义导航控制器中的此方法,b)进入storyboard,单击自定义segue,并输入CustomSegue作为segue类。不幸的是,由于我针对的是iOS 7,因此我收到警告“只有在iOS 9之前支持类名的自定义segues”,并且自定义返回操作现在无法在iOS 7或iOS 8上工作!
2个回答

3
经过多次试验和错误,我找到了一个解决方法。我注意到当你覆盖“segueForUnwindingToViewController”时,“unwindForSegue:towardsViewController”不再被调用,这就是问题所在。据苹果在UIViewController中关于“segueForUnwindingToViewController”的注释说:“Deprecated。返回一个segue,通过“unwindForSegue:towardViewController:”方法从源视图控制器到目标视图控制器进行反向展开。当执行在storyboard中定义的反向展开segue时,如果沿着反向展开路径的任何视图控制器重写了此方法并返回非nil,运行时将使用该segue对象,而不是构造在Interface Builder中指定的类的实例。”粗体字部分似乎没有被实现,即如果您覆盖了此方法但返回值为零,则仍然不会调用“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]; 似乎仍然适用于模态取消segue。我描述的问题似乎发生在show segue上。因此,如果您的设备运行版本小于9.0或segue是模态的,则仍应调用旧方法。如果您在segue是模态的情况下调用 [super unwindForSegue:segue towardsViewController:toViewController];,则该segue将无法工作/发生。


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;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接