我的观点有一个CATiledLayer
。视图控制器具有自定义缩放行为,因此-scrollViewDidEndZooming
每个图块都需要重绘。但是,即使-setNeedsDisplay
每次缩放后都在图层上调用,但并非所有图块都被重绘。这导致视图有时在缩放后看起来不正确。(应该只出现在 1 个图块中的东西出现在多个地方)。它通常会在另一次缩放后自行纠正。
这是相关的代码。updatedRects
用于测试——它存储请求绘制的唯一矩形-drawLayer
。
画布视图.h:
@interface CanvasView : UIView
@property (nonatomic, retain) NSMutableSet *updatedRects;
@end
画布视图.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
对此进行测试时,我总是在缩放后一直滚动到整个视图,以确保看到每个图块。每当视图看起来错误时,预测的“下一个更新的矩形数”大于下一次调用-updateCanvas
. 什么会导致这个?
编辑:
这是可视化问题的更好方法。每次updateCanvas
调用时,我都会让它改变绘制瓷砖的背景颜色并记录它被调用的时间——颜色和时间存储在canvasView
. 在每个图块上绘制图块的矩形、图块沿 x 轴的索引、设置背景颜色的时间(秒)和绘制图块的时间(秒)。如果一切正常,所有的瓷砖应该是相同的颜色。相反,这是我有时会看到的:
缩小后我似乎只看到错误的结果。该问题可能与以下事实有关(编辑:不 - 没有多次调用。)scrollViewDidEndZooming
,因此updateCanvas
每次缩小都会多次调用 。