2011-08-20 38 views
4

我试图使用CATransition从一侧进行推动画。我在处理两个UIViews的方法中执行此操作,一个用于背景,另一个用于前景。动画UIView是前景。但我不希望新内容替换旧内容,因此要将所有旧内容从前景移到后台UIView预计它只会从一侧对UIView的推送过渡进行动画制作,但取而代之的是旧的UIView。有没有办法做我想做的事情,比如锁定UIViews从前景和背景UIViews拥有正确内容的那一刻起的状态?从当前状态为UIView创建CATransition

我的代码是这样的:

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]; 

做的这是我做的,它应该工作(根据苹果的开发者门户),但事实并非如此,所以问题仍然存在。

[编辑]大量的测试和阅读的我发现这个问题是在这之后,当我从它的父删除视图的转换或动画不承认这种变化,直到后来,所以响应过时的最新变化。有没有办法强制更新或检查removeFromSuperviewaddSubview何时完成?

[编辑]我需要的究竟是这样的: 1)UIViews的当前状态为:bgView与阴影的UIView或midView(这种观点不应该被动画)背后旧观点。从不动画的midView。带有当前UIView的fgView。 2)我想将fgView的内容移动到bgView(它不会动画化),并为添加到fgView的新UIView(使用幻灯片,淡入/淡出或翻转动画)的外观设置动画效果。

+0

好像什么,我想在这里做的是无法实现的。嗯......谁会说? – jglievano

+0

你有没有尝试 - [UIView setNeedsDisplay]强制更新你的removeFromSuperview/addSubview调用? – Sam

+0

不幸的是,我不清楚你到底在做什么。是否在两个不同的视图中使用相同的UI元素? UIView只能是一个UIView的子项。另外,为什么你需要为此使用CATransition?使用UIView类方法来转换视图通常更容易。 – Sam

回答

5

也许更好的方法是对旧内容进行“截图”并将截图添加为UIImageView,然后您可以将UIView的内容更改为新内容。

之后,您可以轻松地将动画添加到两个视图中,并且无需担心要更改旧内容。

您可以在下面两个文件添加到您的项目,并得到一个UIView的截图通过调用UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithUIView:view]];

由于这是一个UIImageView,所以你不必担心视图的内容将被改变。

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 
+0

如何在代码中执行此操作? – jglievano

+0

我编辑了我的答案并添加了一些代码。其实这是一个非常简单的动画,你根本不需要CATransition。 UIView的动画方法已经足够好了。 – xuzhe

+0

你会如何使用UIView的动画方法做幻灯片动画?我还需要创建翻转和淡入/淡出动画。另外,我尝试了这个截图方法,动画仍然是这样做的。 – jglievano

3
UIView *newView = argView; // argView is the view passed as a parameter to the method 
// move views from foreground to background 
[fgView.layer removeAllAnimations]; // make sure all, if any, animations are removed. 
for (UIView *v in [fgView subviews]) 
{ 
    // [v removeFromSuperview]; // this should not be needed addSubview does it for you 
    [bgView addSubview:v]; 
} 

// Slide animation 
CATransition *transition = [CATransition animation]; 
transition.duration = 0.5; 
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
transition.type = kCATransitionPush; 
transition.subtype = kCATransitionFromLeft; 
transition.removedOnCompletion = YES; // force removal of animation when completed. 
[fgView addSubview:newView]; 
[fgView.layer addAnimation:transition forKey:nil]; 
+0

我之前尝试过,我从bgView分离fgView。让它们分开的目的是让它们与它们之间的UIView分离,而且不是动画的。 – jglievano

+0

你为什么要在循环中调用'[bgView addSubview:oldView];'?什么是'oldView'? – tidwall

+0

抱歉关于旧视图...是is v。我编辑了示例代码。 – jglievano