我需要在屏幕上绘制多条线(在 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);
}
最佳答案
虽然我理解想要创建多个图层,但将所有线条绘制成一个图层并从那里管理线条列表的动画和旋转会更有效率。您可以在具有组合路径的形状层中执行此操作(缺少标记为“...”的代码):
CGMutablePathRef combinedPath = CGPathCreateMutableCopy(path.CGPath);
for(...)
CGPathAddPath(combinedPath, NULL, [self makeNewPathFrom:...].CGPath);
myLayer.path = combinedPath;
甚至更快,您可以将行列表直接绘制到 graphics context of a CALayer 上.这个 View 的 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。
关于iphone - 绘图线的优化,CAShapeLayer 的可能替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15101821/