2011-08-20 69 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