0

我的 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];
    } 
}

问题:当我放大时,我收到内存警告并且应用程序崩溃。

在分配分析器中,我可以看到应用程序拥有大量内存,但我不明白为什么。当我不调用'setNeedDisplay'我的'redrawForScale'方法时,应用程序不会崩溃。

当我在 drawRect 中记录矩形时,我看到如下值:{{0, 0.299316}, {4688, 6630}}。

4

1 回答 1

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属性)。

于 2012-12-05T13:48:29.523 回答