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 のカスタム redraw メソッドを呼び出します。

メソッドと 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}} のような値が表示されます。

4

1 に答える 1

1

問題は、そのような巨大な CGRect を (再) 描画することです (これが間違っている場合は修正してください)。私にとっての解決策は、カスタム drawRect メソッドの呼び出しを避けることです。一部のスタックオーバーフローの回答 (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 を実装する必要はありません。したがって、maximumZoomScale が大きくても、アプリはクラッシュしません。

UIBezierPath (変換、スケーリング、色の変更) を変更した後、変更した bezierPath を shapeLayer に再度設定する必要があります ( pathshapeLayer の属性を再度設定します)。

于 2012-12-05T13:48:29.523 に答える