优化绘图线,CAShapeLayer的可能替代方案

时间:2013-02-27 00:00:21

标签: iphone ios objective-c optimization cashapelayer

我需要在屏幕上画出很多行(在50-75范围内)并且目前使用以下函数才能正常工作。使用以下代码绘制40-50行后,应用程序在我的iPhone 4中显着减慢。为了优化,我尝试删除它帮助的线阴影,但仍然应用程序运行不如我想要的那么顺畅。我需要优化下面的代码,我的第一个想法是用.png线图像替换cashapelayers。但是新方法应该支持线条旋转,相同宽度的不同长度线和绘图动画(对于我来说,使用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个互补部分,并在一个形状图层中绘制多条线,而不是每次都创建新图层。如果不是很好的话,效果要好得多。这是更新的代码:

+ (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);
}

2 个答案:

答案 0 :(得分:4)

虽然我理解想要创建多个图层,但将所有线条绘制成一个并从那里管理一系列线条的动画和旋转效率会更高效。您可以在具有组合路径的形状图层中执行此操作(缺少标有“...”的代码):

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

更快,您可以直接在graphics context of a 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。

答案 1 :(得分:1)

你肯定想要75层,每层都有自己的线。您确定无法在单个图层中绘制单个更复杂的路径吗?