• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios7 : Custom Push segue pre iOS7 style almost working

[复制链接]
菜鸟教程小白 发表于 2022-12-13 05:29:18 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

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

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap