我正在尝试使用 CATransition
从一侧制作推送动画。我在处理两个 UIViews
的方法中执行此操作,一个用于背景,另一个用于前景。动画 UIView
是前景。但是,我不希望新内容替换旧内容,因此为此我将所有旧内容从前景移动到背景 UIView
期望它只会从一侧为 UIView
的推送过渡设置动画,但它取代了旧的 UIView
。有什么办法可以做我正在尝试做的事情,比如从前景和背景 UIViews
具有正确内容的那一刻起锁定 UIViews
的状态?
我的代码是这样的:
UIView *newView = argView; // argView is the view passed as a parameter to the method
// move views from foreground to background
for (UIView *v in [fgView subviews]) {
[v removeFromSuperview];
[bgView addSubview:v];
}
// Slide animation
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[fgView.layer addAnimation:transition forKey:nil];
[fgView addSubview:newView];
[编辑] 我一直在做一些研究。显然(或者我认为可能正在发生的事情)是背景的 UIViews 移除采用了隐式动画。有没有办法阻止它动画化?
[编辑] 答案:是的,可以做到(禁用隐式动画),并使用以下代码完成
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
for (UIView *v in [fgView subviews]) {
[v removeFromSuperview];
[bgView addSubview:v];
}
[CATransaction commit];
这就是我所做的,它应该可以工作(根据苹果的开发人员门户),但它没有,所以问题仍然存在。
[编辑] 经过大量测试和阅读,我发现问题在于当我从其 super View 中删除 View 时,过渡或动画直到稍后才识别此更改,因此它响应最新更改已过时。有什么方法可以强制更新或检查
removeFromSuperview
或 addSubview
何时完成?[编辑] 我需要的是这个:
1) UIViews 的当前状态是:bgView 带有阴影 UIView 或 midView 后面的旧 View (该 View 不应被动画化)。一个从不动画的 midView。带有当前 UIView 的 fgView。
2)我想将 fgView 的内容移动到 bgView(不会被动画化)并为添加到 fgView 的新 UIView 的外观设置动画(使用幻灯片、淡入/淡出或翻转动画)。
最佳答案
也许更好的方法是对旧内容进行“屏幕截图”并将屏幕截图添加为 UIImageView,然后您可以将 UIView 的内容更改为新内容。
之后,您可以轻松地为两个 View 添加动画,而无需担心旧内容被更改。
您可以将以下两个文件添加到您的项目中,并通过调用 UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithUIView:view]];
获取 UIView 的屏幕截图
因为它是一个 UIImageView,所以你不必担心 View 的内容会被改变。
UIImage+ImagewithUIView.h
@interface UIImage (UIImage+ImagewithUIView)
+ (UIImage *)imageWithUIView:(UIView *)view;
@end
UIImage+ImagewithUIView.m
@implementation UIImage (UIImage+ImagewithUIView)
#pragma mark -
#pragma mark TakeScreenShot
static CGContextRef createBitmapContext(int pixelsWide, int pixelsHigh)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = (kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
CGContextRef bitmapContext = CGBitmapContextCreate(nil, pixelsWide, pixelsHigh, 8, 0, colorSpace, bitmapInfo);
CGColorSpaceRelease(colorSpace);
return bitmapContext;
}
+ (UIImage *)imageWithUIView:(UIView *)view
{
CGSize screenShotSize = view.bounds.size;
CGContextRef contextRef = createBitmapContext(screenShotSize.width, screenShotSize.height);
CGContextTranslateCTM (contextRef, 0, screenShotSize.height);
CGContextScaleCTM(contextRef, 1, -1);
[view.layer renderInContext:contextRef];
CGImageRef imageRef = CGBitmapContextCreateImage(contextRef);
CGContextRelease(contextRef);
UIImage *img = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
// return the image
return img;
}
@end
关于iphone - 从当前状态为 UIView 创建 CATransition,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7132620/