我的UIView结构:
我有一个"master"
UIView(实际上UIScrollView
,但它的目的只是滚动每个分页)。
作为此"master"
上的子视图,我有"pageView"
(UIScrollView
的子类)。此UIScrollView
可以包含任何内容(例如UIImageView)。
"master"
有另一个子视图:PaintView
(UIView的子类)。通过这个视图,我可以跟踪手指的移动并绘制它。
结构如下:
[master.view addSubview: pageView];
[master.view addSubview: paintView];
我知道当用户放大(pageView负责此操作)和委托/方法调用时,我会在缩放操作期间根据缩放更改更改paintView
的帧。
缩放(scrollViewDidEndZooming:withView:atScale)
后,我调用paintView的自定义重绘方法。
重绘方法和drawRect:
-(void)redrawForScale:(float)scale {
for (UIBezierPath *path in _pathArray) {
//TransformMakeScale...
}
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect {
for (UIBezierPath *path in _pathArray) {
[path strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
}
}
问题: 当我放大时,我收到内存警告,应用程序崩溃。
在Allocations探查器中,我可以看到应用程序拥有大量内存,但我看不出原因。
如果我在'setNeedDisplay'
方法后没有拨打'redrawForScale'
,那么应用就不会崩溃。
当我在drawRect中记录rect时,我看到如下值:{{0,0.299316},{4688,6630}}。
答案 0 :(得分:1)
问题是(重新)绘制如此巨大的CGRect(如果这是错误的,请纠正我)。
对我来说,解决方案是避免调用自定义drawRect方法。在一些stackoverflow答案中(我想在Appls文档的某个地方),有人提到自定义drawRect:
会降低性能(因为iOS无法在自定义drawRect方法上做一些魔术)。
我的解决方案:
使用CAShapeLayer
。对于每个UIBezierPath,我创建一个CAShapeLayer实例,将UIBezierPath添加到图层的path
属性,并将该图层作为子图层添加到我的视图中。
CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] initWithLayer:self.layer];
shapeLayer.lineWidth = 10.0;
shapeLayer.strokeColor = [UIColor blackColor].CGColor;
shapeLayer.fillColor = [UIColor clearColor].CGColor;
shapeLayer.path = myBezierPath.CGPath;
[self.layer addSublayer:shapeLayer];
使用此解决方案,我不需要实现drawRect。因此即使有一个很大的最大缩放比例,应用程序也不会崩溃。
更改UIBezierPath(翻译,缩放,更改颜色)后,我需要再次将更改后的bezierPath设置为shapeLayer(再次设置shapeLayer的path
属性。)