多くのUIViewサブビューを含むUIScrollView内にUIViewがあります。これらの各サブビューには、CATiledLayerレイヤーがあります。さらに、(すべてのサブビューとともに)コンテキスト内にコンテナーUIViewを描画する拡大ルーペ機能があります。関連するコード:
これは、ルーペのdrawRectメソッドです。
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextClipToMask( context , loupeRect, self.maskImage);
CGContextSetFillColorWithColor(context, [[UIColor whiteColor] CGColor]);
CGContextFillRect(context, loupeRect);
CGContextSaveGState( context );
CGContextScaleCTM(context, gridScale, gridScale);
CGContextTranslateCTM(context, offset.x, offset.y);
CGRect rectToDraw = CGRectMake(-offset.x, -offset.y, 512, 512);
[appDelegate.gridViewController.objectContainerView drawInContext:context forRect:rectToDraw];
CGContextRestoreGState( context );
[overlayImage drawAtPoint:CGPointZero];
}
そして、これは、サブビューが描画されるコンテナUIViewのdrawInContext:forRectメソッドです。
- (void)drawInContext:(CGContextRef)ctx forRect:(CGRect)rect {
CGRect newrect = CGRectMake(rect.origin.x-1024, rect.origin.y-1024, 2048, 2048);
for (UIView* v in [self subviews]) {
float viewscale = v.transform.a;
if (CGRectIntersectsRect(newrect,v.frame)) {
CGContextSaveGState(ctx);
CGContextScaleCTM(ctx, viewscale, viewscale);
CGContextTranslateCTM(ctx, v.frame.origin.x/viewscale, v.frame.origin.y/viewscale);
[v drawLayer:v.layer inContext:ctx];
CGContextRestoreGState(ctx);
}
}
[super drawLayer:self.layer inContext:ctx];
}
そして最後に、これはCATiledLayerを使用したサブビューのdrawRectメソッドです。
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat scale = CGContextGetCTM(context).a;
scale = (scale <= .125) ? .125 : (scale <= .250 ? .250 : (scale <= .5 ? .5 : 1));
CATiledLayer *tiledLayer = (CATiledLayer *)[self layer];
CGSize tileSize = tiledLayer.tileSize;
tileSize.width /= scale;
tileSize.height /= scale;
int firstCol = floorf(CGRectGetMinX(rect) / tileSize.width);
int lastCol = floorf((CGRectGetMaxX(rect)-1) / tileSize.width);
int firstRow = floorf(CGRectGetMinY(rect) / tileSize.height);
int lastRow = floorf((CGRectGetMaxY(rect)-1) / tileSize.height);
for (int row = firstRow; row <= lastRow; row++) {
for (int col = firstCol; col <= lastCol; col++) {
UIImage *tile = [self tileForScale:scale row:row col:col];
CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row,
tileSize.width, tileSize.height);
tileRect = CGRectIntersection(self.bounds, tileRect);
[tile drawInRect:tileRect];
}
}
}
これで、すべてが意図したとおりに機能しますが、拡大ループがオンになっていて移動していると、アプリの速度が大幅に低下します。問題は、ルーペビューが移動されるたびに、そのdrawRectメソッドが呼び出され(拡大されたコンテンツを更新できるようにするため)、その後、コンテナUIViewなどのdrawInContextメソッドが呼び出されることです...その結果、すべてのCATiledLayersが画像を更新しますルーペが動かされるたびにタイル。
ご覧のとおり、ルーペのコンテキスト内でコンテナビューの大部分を描画しようとしましたが、これが行き詰まっています。このコンテナビューの大部分を「バッファリング」する方法がわかりません。そのため、ルーペを移動すると、再描画される四角形が「バッファリングされた」四角形を超えた場合にのみ、サブビューが再描画されます。
コードがずさんな/新しい場合は申し訳ありません-私はその真っ只中にいて、助けを探しています。
ありがとう!