ios7:自定义推送序列ios7之前的样式几乎正常工作

ios7:自定义推送序列ios7之前的样式几乎正常工作,ios,segue,Ios,Segue,我已经尝试制作一个自定义segue来模拟iOS6中的旧segue推送,因为新的推送segue不能很好地与我的应用程序配合使用 -(void)perform { UIViewController *sourceViewController = (UIViewController*)[self sourceViewController]; UIViewController *destinationController = (UIViewController*)[self desti

我已经尝试制作一个自定义segue来模拟iOS6中的旧segue推送,因为新的推送segue不能很好地与我的应用程序配合使用

-(void)perform {

    UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
    UIViewController *destinationController = (UIViewController*)[self destinationViewController];

    CATransition* transition = [CATransition animation];
    transition.duration = 1.5;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
    transition.subtype = kCATransitionFromRight; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom



    [sourceViewController.navigationController.view.layer addAnimation:transition
                                                                forKey:kCATransition];

    [sourceViewController.navigationController pushViewController:destinationController animated:NO];

}

所有东西都嵌入到导航控制器中。我已将延伸边缘标记为“顶部钢筋下方”和“底部钢筋下方”。我在两个视图控制器(源和目标)中都有一个自定义的视图背景色。在这两个视图控制器之间的转换过程中,导航栏开始在两个视图控制器的白色和我的自定义背景色之间闪烁。知道为什么吗?

代码中的问题是:

触发
pushViewController
方法时,会立即从导航堆栈中删除
sourceViewController
,并显示
destinationViewController
。 这会导致动画中出现问题(该问题甚至在iOS 6上也存在,导致另一个问题,即“黑色褪色”)。 如果您仍然想使用
pushViewController
(这更容易,因为您不需要重新构建导航逻辑),您必须按照苹果的建议进行操作

无论您如何执行动画,在动画结束时,您都要负责在正确的位置安装目标视图控制器(及其视图),以便它能够处理事件。例如,如果要实现自定义模式转换,可以使用快照图像执行动画,然后在结束时调用presentModalViewController:animated:方法(禁用动画)在源视图控制器和目标视图控制器之间设置适当的模式关系

您应该使用快照

此处更新了您的执行方法:

- (void)perform
{
    UIViewController *source = (UIViewController *) self.sourceViewController;
    UIViewController *destination = (UIViewController *) self.destinationViewController;

    // Swap the snapshot out for the source view controller
    UIWindow *window = source.view.window;
    UIImageView *screenShot = [[UIImageView alloc] initWithImage:[self screenshot]];

    BOOL animsEnabled = [UIView areAnimationsEnabled];
    [UIView setAnimationsEnabled:NO];

    [window addSubview:screenShot];

    [UIView setAnimationsEnabled:animsEnabled];

    CATransition* transition = [CATransition animation];
    transition.duration = 1.5;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
    transition.subtype = kCATransitionFromRight; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
    [source.navigationController pushViewController:destination animated:NO];
    [destination.navigationController.view.layer addAnimation:transition forKey:kCATransition];


    [UIView animateWithDuration:1.5f animations:^{
        screenShot.frame = CGRectOffset(screenShot.frame, -screenShot.frame.size.width, 0);
    } completion:^(BOOL finished) {
        [screenShot removeFromSuperview];
    }];
}
要进行正确的屏幕截图,仅使用
renderInContext
方法是不够的,因为半透明条的模糊没有得到正确的管理。 我找到了另一种方法(从问题中复制和粘贴)


我附上一个示例项目,展示它是如何工作的:

代码中的问题是:

触发
pushViewController
方法时,会立即从导航堆栈中删除
sourceViewController
,并显示
destinationViewController
。 这会导致动画中出现问题(该问题甚至在iOS 6上也存在,导致另一个问题,即“黑色褪色”)。 如果您仍然想使用
pushViewController
(这更容易,因为您不需要重新构建导航逻辑),您必须按照苹果的建议进行操作

无论您如何执行动画,在动画结束时,您都要负责在正确的位置安装目标视图控制器(及其视图),以便它能够处理事件。例如,如果要实现自定义模式转换,可以使用快照图像执行动画,然后在结束时调用presentModalViewController:animated:方法(禁用动画)在源视图控制器和目标视图控制器之间设置适当的模式关系

您应该使用快照

此处更新了您的执行方法:

- (void)perform
{
    UIViewController *source = (UIViewController *) self.sourceViewController;
    UIViewController *destination = (UIViewController *) self.destinationViewController;

    // Swap the snapshot out for the source view controller
    UIWindow *window = source.view.window;
    UIImageView *screenShot = [[UIImageView alloc] initWithImage:[self screenshot]];

    BOOL animsEnabled = [UIView areAnimationsEnabled];
    [UIView setAnimationsEnabled:NO];

    [window addSubview:screenShot];

    [UIView setAnimationsEnabled:animsEnabled];

    CATransition* transition = [CATransition animation];
    transition.duration = 1.5;
    transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    transition.type = kCATransitionPush; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
    transition.subtype = kCATransitionFromRight; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
    [source.navigationController pushViewController:destination animated:NO];
    [destination.navigationController.view.layer addAnimation:transition forKey:kCATransition];


    [UIView animateWithDuration:1.5f animations:^{
        screenShot.frame = CGRectOffset(screenShot.frame, -screenShot.frame.size.width, 0);
    } completion:^(BOOL finished) {
        [screenShot removeFromSuperview];
    }];
}
要进行正确的屏幕截图,仅使用
renderInContext
方法是不够的,因为半透明条的模糊没有得到正确的管理。 我找到了另一种方法(从问题中复制和粘贴)


我附加了一个示例项目来说明它是如何工作的:

这可能是因为在执行动画时正在推送未设置动画的视图控制器。试着先推然后做动画我真的不知道你是什么意思?你能举个例子吗?我想你可以试试Patrick的答案,他建议你把[sourceViewController.navigationController pushViewController:destinationController动画:否];动画代码之前的代码。@MichiZH我添加了一个带有工作代码的答案和一个示例项目,请检查它是否适合赏金;-)这可能是因为在执行动画时正在推送未设置动画的视图控制器。试着先推然后做动画我真的不知道你是什么意思?你能举个例子吗?我想你可以试试Patrick的答案,他建议你把[sourceViewController.navigationController pushViewController:destinationController动画:否];动画代码之前的代码。@MichiZH我添加了一个带有工作代码的答案和一个示例项目,请检查它是否适合赏金;-)是的;-)快乐编码是的;-)快乐编码