私のUIViewのサブクラスは、サブレイヤーを多用して複雑な画像を作成します。画面上にはこれらのビューが最大30個あり、iPad 2ではperimeterPath(perimeterLayerのパス属性)に沿ったアニメーションのパフォーマンスが低下していました。
元々、ビューのレイヤーにサブレイヤーとして構成レイヤーを追加するだけでした。
[self.layer addSublayer:self.leftsideLayer]; // CAShapeLayer
[self.layer addSublayer:self.rightsideLayer]; // CAShapeLayer
[self.layer addSublayer:self.perimeterLayer]; // CAShapelayer
[self.layer addSublayer:self.valueLayer]; // CAShapeLayer
[self.layer insertSublayer:self.gradientLayer atIndex:0]; // CAGradientLayer + CAShapeLayer (as mask)
画面上のレンダリングは完璧です。しかし、アニメーションが遅れ始めていたので、一時レイヤーをビットマップにレンダリングすることを目的として、一時レイヤーにビルドするためにこのコードを準備しました。ステップ1は、既存のコードを少しやり直すことができるようにすることでした。
CALayer *tmpLayer = [CALayer layer];
[tmpLayer addSublayer:self.leftsideLayer]; // CAShapeLayer
[tmpLayer addSublayer:self.rightsideLayer]; // CAShapeLayer
[tmpLayer addSublayer:self.perimeterLayer]; // CAShapelayer
[tmpLayer addSublayer:self.valueLayer]; // CAShapeLayer
[tmpLayer insertSublayer:self.gradientLayer atIndex:0]; // CAGradientLayer + CAShapeLayer (as mask)
[self.layer addSublayer:tmpLayer];
予想通り、それはうまくいきました。
次のステップは、これらすべてのレイヤーの事前レンダリングされたバージョンを生成することです。
// [self.layer addSublayer:tmpLayer];
UIGraphicsBeginImageContextWithOptions([self bounds].size, YES, 0.0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self drawLayer:tmpLayer inContext:ctx];
UIImage *renderedImageOfMyself = UIGraphicsGetImageFromCurrentImageContext();
if (!renderedImageOfMyself) {
NSLog(@"Well that didn't work");
}
UIGraphicsEndImageContext();
[self.layer setContents:renderedImageOfMyself.CGImage];
その結果、画面に黒い長方形が表示されたので、次に試してみました。
// [self.layer setContents:renderedImageOfMyself.CGImage];
[self addSubview:[[UIImageView alloc] initWithImage:renderedImageOfMyself]];
それはまた私に黒い長方形を与えているので、私は画面上で黒い長方形を取得するどちらの方法でもうまくいくと結論付けました;-)しかし、私はどういうわけかトップレイヤーをビットマップグラフィックスコンテキストにレンダリングするのを台無しにしました。
新しいコンテキストを開始する際のオプションの部分、YESとNO、1.0と0.0をいじってみました。すべて無駄に。
次のプロセスで何が欠けていますか:
- 新しいグラフィックコンテキストを開始します
- そのコンテキストに私のレイヤーを描画します
- そのコンテキストから画像を取得します
?
ありがとう!