私の見解にはCATiledLayer
。ビューコントローラにはカスタムズーム動作があるため、-scrollViewDidEndZooming
すべてのタイルを再描画する必要があります。ただし、-setNeedsDisplay
ズームするたびにレイヤーで呼び出されても、すべてのタイルが再描画されるわけではありません。これにより、ズーム後にビューが正しく表示されない場合があります。(1つのタイルに表示されるはずのものが複数の場所に表示されています)。多くの場合、別のズーム後に自動的に修正されます。
関連するコードは次のとおりです。updatedRects
テスト用です-によって描画するように要求された一意の長方形を格納し-drawLayer
ます。
CanvasView.h:
@interface CanvasView : UIView
@property (nonatomic, retain) NSMutableSet *updatedRects;
@end
CanvasView.m:
@implementation CanvasView
@synthesize updatedRects;
+ (Class)layerClass
{
return [CATiledLayer class];
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)context
{
CGRect rect = CGContextGetClipBoundingBox(context);
[updatedRects addObject:[NSValue valueWithCGRect:rect]];
CGContextSaveGState(context);
CGContextTranslateCTM(context, rect.origin.x, rect.origin.y);
// ...draw into context...
CGContextRestoreGState(context);
}
@end
MyViewController.m:
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
canvasView.updatedRects = [NSMutableSet set];
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{
canvasView.transform = CGAffineTransformIdentity;
canvasView.frame = CGRectMake(0, 0, canvasView.frame.size.width * scale, canvasView.frame.size.height);
[self updateCanvas];
}
- (void)updateCanvas
{
NSLog(@"# rects updated: %d", [canvasView.updatedRects count]);
[canvasView.updatedRects removeAllObjects];
canvasView.frame = CGRectMake(canvasView.frame.origin.x, canvasView.frame.origin.y, canvasView.frame.size.width, myHeight);
CGFloat tileSize = 256;
NSLog(@"next # rects updated will be: %f", [canvasView.layer bounds].size.width / tileSize);
[canvasView.layer setNeedsDisplay];
}
@end
これをテストするとき、ズームした後は常にビュー全体をスクロールして、すべてのタイルが表示されていることを確認しました。ビューが間違っているように見えるときはいつでも、予測された「更新されたrectの次の数」は、への次の呼び出しでの実際の「更新されたrectの数」よりも大きかった-updateCanvas
。これは何が原因でしょうか?
編集:
問題を視覚化するためのより良い方法は次のとおりです。が呼び出されるたびupdateCanvas
に、タイルを描画するための背景色を変更し、呼び出された時刻を記録するようにしました。色と時刻はに保存されcanvasView
ます。各タイルには、タイルの長方形、x軸に沿ったタイルのインデックス、背景色が設定された時間(秒)、およびタイルが描画された時間(秒)が描画されます。すべてが正しく機能している場合は、すべてのタイルが同じ色である必要があります。代わりに、これが私が時々見ているものです:
ズームアウトした後、間違った結果が表示されるだけのようです。この問題は、がズームアウトごとに複数回呼び出される可能性があるという事実に関連している可能性があります(編集:いいえ-複数回呼び出されません。)scrollViewDidEndZooming
。updateCanvas