2

iOS では、ビューに複数のレイヤーがある場合、drawRectメソッドは表示するレイヤーを 1 つだけ選択し、1 秒後に表示する別のレイヤーを選択して、アニメーション効果を実現できますか?

現在、いくつかのレイヤーがありますが、ビューのレイヤーではないと思います(親レイヤーのサブレイヤーではない個々のレイヤーにすぎません)。

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

drawRect、私は使用します

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

レイヤーをビューに描画するには...動作しますが、これはレイヤーをレイヤーに描画する(ビューのレイヤーにレイヤーを描画する)ようなものではありませんか?ビューに使用するように指示する、layer1または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選択した に設定することで、同じ種類の効果を得る同様の方法を次に示します。

-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 に答える