OStack程序员社区-中国程序员成长平台

标题: ios7 : Custom Push segue pre iOS7 style almost working [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 05:29
标题: ios7 : Custom Push segue pre iOS7 style almost working

我尝试制作自定义 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];

}

一切都嵌入在导航 Controller 中。我已将延伸边缘标记为“在顶部栏下方”和“在底部栏下方”。而且我在两个 View Controller (源和目标)中都有 View 的自定义背景颜色。在这两个 View Controller 之间的过渡期间,导航栏开始在白色和两个 View Controller 的自定义背景颜色之间闪烁。知道为什么吗?



Best Answer-推荐答案


你的代码中的问题是这样的:

当你触发 pushViewController 方法时,sourceViewController 立即从导航堆栈中移除,destinationViewController 出现。 这会导致动画出现问题(即使在 iOS 6 上也存在问题,导致另一个问题,即“黑色渐变”)。 如果您仍想使用 pushViewController (这更容易,因为您不需要重建导航逻辑),您必须按照 Apple here 的建议进行操作

Regardless of how you perform the animation, at the end of it, you are responsible for installing the destination view controller (and its views) in the right place so that it can handle events. For example, if you were to implement a custom modal transition, you might perform your animations using snapshot images and then at the end call the presentModalViewController:animated: method (with animations disabled) to set up the appropriate modal relationship between the source and destination view controllers.

您应该使用快照。

这里你的 perform 方法更新了:

- (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 方法是不够的,因为半透明条的模糊没有正确管理。 我找到了另一种方法(从 THIS 问题复制和粘贴)

- (UIImage *)screenshot
{
    CGSize imageSize = CGSizeZero;

    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
    if (UIInterfaceOrientationIsPortrait(orientation)) {
        imageSize = [UIScreen mainScreen].bounds.size;
    } else {
        imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
    }

    UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
        CGContextSaveGState(context);
        CGContextTranslateCTM(context, window.center.x, window.center.y);
        CGContextConcatCTM(context, window.transform);
        CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
        if (orientation == UIInterfaceOrientationLandscapeLeft) {
            CGContextRotateCTM(context, M_PI_2);
            CGContextTranslateCTM(context, 0, -imageSize.width);
        } else if (orientation == UIInterfaceOrientationLandscapeRight) {
            CGContextRotateCTM(context, -M_PI_2);
            CGContextTranslateCTM(context, -imageSize.height, 0);
        } else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
            CGContextRotateCTM(context, M_PI);
            CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
        }
        if ([window respondsToSelectorselector(drawViewHierarchyInRect:afterScreenUpdates]) {
            [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
        } else {
            [window.layer renderInContext:context];
        }
        CGContextRestoreGState(context);
    }

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

我附上了一个示例项目,展示了它是如何工作的:Link to sample project

关于ios7 : Custom Push segue pre iOS7 style almost working,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19978130/






欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) Powered by Discuz! X3.4