我的观点有一个CATiledLayer.视图控制器具有自定义缩放行为,因此-scrollViewDidEndZooming需要重新绘制每个tile.但是,即使在每次缩放后在图层上调用-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,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每次缩小多次调用的事实有关. (编辑:不 – 不多次调用.)
解决方法
有一个相当昂贵的黑客可能对你有用:
tiledLayer.contents = nil; [tiledLayer setNeedsDisplayInRect:tiledLayer.bounds];
如果我没记错的话,第一行实际上将平铺图层转换为普通图层,但第二行将其转回.但是,它会将所有内容都丢弃在平铺层中.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。