3

画面に多くの線(50〜75の範囲)を描画する必要がありますが、現在は以下の関数を使用して正常に動作します。以下のコードでこれらの線を40〜50本描画した後、iPhone 4でアプリケーションの速度が著しく低下します。最適化するために、線の影を削除しようとしましたが、それでもアプリは思ったほどスムーズに実行されませんでした。以下のコードを最適化する必要があります。私の最初のアイデアは、cashapelayersを.pngラインイメージに置き換えることです。ただし、新しいメソッドは、線の回転、同じ幅の異なる長さの線、および描画のアニメーションをサポートする必要があります(cgaffinetransformsを使用することは私にとって多くのことのようです)。私を助けることができるアイデアはありますか?

+ (CAShapeLayer *) drawLineOnView:(UIView *) view BetweenPoint1:(CGPoint) point1 Point2:(CGPoint) point2 lineWidth:(CGFloat)lineWidth lineColor:(UIColor *) color Animated:(BOOL) animed
{
    CAShapeLayer *lineShape = [CAShapeLayer layer];
    CGMutablePathRef linePath = nil;
    linePath = CGPathCreateMutable();

    //lineShape.opacity = 0.6;
    lineShape.lineWidth = lineWidth;
    lineShape.lineCap = kCALineCapRound;

    if(color==nil) color = [UIColor orangeColor]; //Default value
    lineShape.shadowColor = [color CGColor];
    lineShape.shadowOpacity = 1.0;
    lineShape.shadowRadius = 5.0;
    lineShape.strokeColor = [color CGColor];

    CGPathMoveToPoint(linePath, NULL, point1.x, point1.y);
    CGPathAddLineToPoint(linePath, NULL, point2.x, point2.y);

    if(animed)
    {
        CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
        pathAnimation.duration = 1.0;
        pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
        pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
        [lineShape addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
    }

    lineShape.path = linePath;
    CGPathRelease(linePath);
    [view.layer addSublayer:lineShape];

    return lineShape;
}

部分的に解決済み(最適化は終了しません)

線画機能を2つの補完的な部分に分割し、毎回新しいレイヤーを作成するのではなく、複数の線を1つのシェイプレイヤーに描画しました。素晴らしいとは言えないにしても、はるかにうまく機能します。更新されたコードは次のとおりです。

+ (CAShapeLayer *) createNewShapeLayerForDrawingLinesOnView:(UIView *) view lineWidth:(CGFloat)lineWidth lineColor:(UIColor *) color
{
    CAShapeLayer *lineShape = [CAShapeLayer layer];

    //lineShape.opacity = 0.6;
    lineShape.lineWidth = lineWidth;
    lineShape.lineCap = kCALineCapRound;

    if(color==nil) color = [UIColor orangeColor]; //Default value
    lineShape.shadowColor = [color CGColor];
    lineShape.shadowOpacity = 1.0;
    lineShape.shadowRadius = 5.0;
    lineShape.strokeColor = [color CGColor];

    [view.layer addSublayer:lineShape];
    return lineShape;
}

+ (void) addNewLineToShapeLayer:(CAShapeLayer *) shapeLayer BetweenPoint1:(CGPoint) point1 Point2:(CGPoint) point2
{
    CGMutablePathRef combinedPath = CGPathCreateMutableCopy(shapeLayer.path);

    CGMutablePathRef linePath = CGPathCreateMutable();

    CGPathMoveToPoint(linePath, NULL, point1.x, point1.y);
    CGPathAddLineToPoint(linePath, NULL, point2.x, point2.y);

    //No paths drawn before
    if(combinedPath == NULL)
    {
        combinedPath = linePath;
    }
    else
    {
        CGPathAddPath(combinedPath, NULL, linePath);
    }

    shapeLayer.path = combinedPath;
    CGPathRelease(linePath);
}
4

2 に答える 2

4

複数のレイヤーを作成したいのは理解していますが、すべての線を1つに描画し、そこから線のリストのアニメーションと回転を管理する方がはるかに効率的です。これは、次のような結合されたパスを持つシェイプレイヤーで実行できます(「...」でマークされたコードがありません):

CGMutablePathRef combinedPath = CGPathCreateMutableCopy(path.CGPath);
for(...)
    CGPathAddPath(combinedPath, NULL, [self makeNewPathFrom:...].CGPath);
myLayer.path = combinedPath;

さらに高速に、線のリストをCALayerのグラフィックスコンテキストに直接描画できます。ビューのdrawRect:メソッドのこの例はテストされていませんが、アイデアが得られるはずです。

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetLineWidth(context, lineWidth);
CGContextSetRGBStrokeColor(context, 1.0, 0.0, 0.0, 1.0); //red

for(MyLine *line in lines)
{
    CGContextMoveToPoint(context, point1.x, point1.y);
    CGContextAddLineToPoint(context, point2.x, point2.y);
}

さらに最適化が必要な場合は、OpenGLを調べる必要があります。

于 2013-02-27T00:12:09.697 に答える
1

それぞれが独自のラインを持つ75のレイヤーは絶対に必要ありません。単一のレイヤーに単一の、より複雑なパスを描画することはできませんか?

于 2013-02-27T00:30:34.333 に答える