2

在iOS上,如果一个view有好几层,那么该drawRect方法是否可以选择任意一层显示,1秒后选择另一层显示,实现动画效果?

现在,我有几个图层,但我不认为它们是视图的图层(它们只是单独的图层,不是父图层的子图层),因为我只是使用创建它们

CGLayerCreateWithContext(context, self.view.bounds.size, NULL);

在 中drawRect,我使用

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

将图层绘制到视图上......它可以工作,但这不是像在图层上绘制图层(在视图图层上绘制图层)吗?没有更快的方法,那就是告诉视图使用layer1or layer2,有点像

self.layer = layer1;  

但它不能,因为它layer是只读的。这可以实现吗?

4

2 回答 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 个纯色视图,并可能整理实例变量。这只是一个基本的代码示例,可以满足您的需求。

于 2012-05-27T07:20:11.470 回答
3

遵循@PartiallyFinite 的示例,通过将视图的图层contents属性设置CGImage为您选择的 a,这是获得相同效果的类似方法。

这比-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
于 2012-05-27T08:08:47.213 回答