2012-05-27 36 views
2

在iOS上,如果一個視圖有多個圖層,那麼drawRect方法是否可以選擇任何一個要顯示的圖層,然後在1秒後選擇另一個要顯示的圖層來實現動畫效果?在iOS上,如果一個視圖有多個圖層,drawRect只需選擇一個要顯示的圖層?

現在,我有好幾層,但我不認爲他們是視圖的層(它們是不是父層的子層只是單獨的層),因爲我只是用

CGLayerCreateWithContext(context, self.view.bounds.size, NULL); 
創造了他們

drawRect,我用

CGContextDrawLayerAtPoint(context, self.bounds.origin, layer1); 

的層繪製到視圖...它的工作原理,但不是這個如畫層到層(繪製層到視圖的層)?是不是有一個更快的方法,這是告訴視圖使用​​或layer2,有點像

self.layer = layer1; 

但不能因爲layer是隻讀的。這可以實現嗎?

+0

您是否試圖通過讓每個幀位於單獨的圖層並交換圖層來實現動畫? – Greg

+1

這個問題沒有什麼意義,因爲你混淆了兩個不同的東西:'CGLayer's和'CALayer's。他們有相似的名字,但他們*完全不同*。你不能混合和匹配它們。 'CGLayerCreateWithContext'生成一個'CGLayer',但'self.layer'是一個'CALayer'。 –

+0

@PartiallyFinite yes ... 2層,例如,使用這兩層的動畫...... –

回答

3

您正在嘗試繪製CALayer使用CGLayer繪圖方法的對象。這些是不同的事情,不會互換。但是,如果我正確理解了您的問題,則根本不需要使用drawRect:在一段時間之後在層之間切換。這是我的基本工作代碼示例:

#import <QuartzCore/QuartzCore.h> 

@interface TTView { 
    NSUInteger index; 
    NSArray *layers; 
    CALayer *currentLayer; 
} 

@end 

@implementation TTView 

- (void)switchView { 
    // Remove the currently visible layer 
    [currentLayer removeFromSuperlayer]; 

    // Add in the next layer 
    currentLayer = [layers objectAtIndex:index]; 
    [self.layer addSublayer:currentLayer]; 

    // Increment the index for next time 
    index += 1; 
    if (index > [layers count] - 1) { 
     // If we have reached the end of the array, go back to the start. You can exit the loop here by calling a different method followed by return; 
     index = 0; 
    } 

    // Call this method again after 1 second 
    [self performSelector:@selector(switchView) withObject:nil afterDelay:1]; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder { 
    // Basic initialisation. Move this to whatever method your view inits with. 
    self = [super initWithCoder:aDecoder]; 
    if (self) { 
     // Create some random objects with layers to display. Place your layers into the array here. 
     UIView *a = [[UIView alloc] initWithFrame:self.bounds]; 
     a.backgroundColor = [UIColor redColor]; 
     UIView *b = [[UIView alloc] initWithFrame:self.bounds]; 
     b.backgroundColor = [UIColor greenColor]; 
     UIView *c = [[UIView alloc] initWithFrame:self.bounds]; 
     c.backgroundColor = [UIColor blueColor]; 

     // Add the layers to the array. 
     layers = [[NSArray alloc] initWithObjects:a.layer, b.layer, c.layer, nil]; 
     // Call the method to start the loop. 
     [self switchView]; 
    } 
    return self; 
} 

很顯然,你應該與任何層您打算以這種方式製作動畫,並有可能收拾實例變量替換我的3層素色的意見。這只是一個簡單的代碼示例,可以實現您想要的功能。

+0

所以如果第一層要在裏面畫一個矩形,而第二層需要在裏面畫一個圓,那怎麼做?我嘗試使用'FooView'而不是'UIView' ...並在'FooView'中使用'drawRect'來繪製它...但圖層完全是黑色的...(但是如果我再次想到......' drawRect'由運行循環調用'keyWindow'(頂視圖)的視圖層次結構,在...上面的代碼示例中,沒有爲這些視圖調用'drawRect'的概念。) –

3

以下是@ PartiallyFinite的示例,通過將您視圖的圖層的contents屬性設置爲您選擇的CGImage,獲得相同類型效果的方法類似。

這比覆蓋-drawRect:並在那裏繪製效率更高,因爲它避免了額外的繪製操作並上傳到視頻硬件。

#import <QuartzCore/QuartzCore.h> 

@interface TTView { 
    NSUInteger index; 
    NSMutableArray *images; 
} 

@end 

@implementation TTView 

- (id)initWithCoder:(NSCoder *)aDecoder { 
    // Basic initialisation. Move this to whatever method your view inits with. 
    self = [super initWithCoder:aDecoder]; 
    if (self) { 
     // Create some random images to display. Place your images into the array here. 
     CGSize imageSize = self.bounds.size;   
     images = [[NSMutableArray alloc] init]; 
     [images addObject:[self imageWithSize:imageSize color:[UIColor redColor]]]; 
     [images addObject:[self imageWithSize:imageSize color:[UIColor greenColor]]]; 
     [images addObject:[self imageWithSize:imageSize color:[UIColor blueColor]]]; 

     [self switchView]; 
    } 
    return self; 
} 

- (UIImage*)imageWithSize:(CGSize)imageSize color:(UIColor*)color { 
    UIGraphicsBeginImageContext(imageSize); 

    // Draw whatever you like here. 
    // As an example, we just fill the whole image with the color. 
    [color set]; 
    UIRectFill(CGRectMake(0, 0, imageSize.width, imageSize.height)); 

    UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return image; 
} 

- (void)switchView { 
    UIImage* image = [images objectAtIndex:index]; 
    self.layer.contents = (id)(image.CGImage); 

    index = (index + 1) % images.count; 

    [self performSelector:@selector(switchView) withObject:nil afterDelay:1]; 
} 

// DO NOT override -drawRect:, and DO NOT call -setNeedsDisplay. 
// You're already providing the view's contents. 

@end 
+0

hm ...'self.layer.contents = [images objectAtIndex:index] .CGImage;'現在會說'CGImage'是一個沒有找到的屬性...我試圖將第一部分轉換爲'(UIImage *)'但仍然錯誤 –

+0

,使線,如果它是''self.layer.contents =(id)((UIImage *)[images objectAtIndex:index])。CGImage;' –

+0

是的,對不起,我錯過了添加到' id)'那裏。固定。 –

相關問題