gpt4 book ai didi

ios7 : Custom Push segue pre iOS7 style almost working

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:44:47 25 4
gpt4 key购买 nike

我尝试制作自定义转场来模拟来自 iOS6 的旧转场推送,因为新的推送转场不能很好地与我的应用程序配合使用。

-(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 中。我已将延伸边缘标记为“Under Top Bars”和“Unter Bottom Bars”。我在两个 View Controller (源和目标)中都有 View 的自定义背景颜色。在这两个 View Controller 之间的转换期间,导航栏开始在两个 View Controller 的白色和我的自定义背景颜色之间闪烁。知道为什么吗?

最佳答案

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

当您触发 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.

您应该使用快照。

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

- (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 respondsToSelector:@selector(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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com