我正在开发一个基本的绘图应用程序,它有几个类。其中一个是“Line”类,它在用户可以绘制的一行上存储一些信息。当用户在屏幕上拖动时,为他们的手指的每次移动创建一条线,因此在他们的手指之后绘制一条线。我将所有线对象存储在NSArray中,并在每次更改时重绘。但是,由于阵列不断变大,最终开始变慢。有没有办法只为这些线绘制新的线条或更好的存储机制?
编辑:
阅读下面的答案,但setNeedsDisplayInRect:
似乎不起作用。我这样称呼它:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *t in touches) {
//add line to array w/ x and y values from touch
[self setNeedsDisplayInRect:[self rectForLine:line]];
}
}
-(CGRect)rectForLine:(Line*)line {
CGFloat x1 = [line begin].x;
CGFloat y1 = [line begin].y;
CGFloat x2 = [line end].x;
CGFloat y2 = [line end].y;
CGFloat originX = (x1>x2) ? x1 : x2;
CGFloat originY = (y1<y2) ? y1 : y2;
CGFloat diffX = ((x1>x2) ? x1 : x2) - originX;
CGFloat diffY = ((y1>x2) ? y1 : y2) - originY;
return CGRectMake(originX, originY, diffX, diffY);
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, 10.0);
CGContextSetLineCap(context, kCGLineCapRound);
//[[UIColor blackColor] set];
for (Line *line in completeLines) {
if (CGRectContainsPoint(rect, [line begin]) && CGRectContainsPoint(rect, [line end])) {
//draw line onto the screen
}
}
答案 0 :(得分:2)
如果“行”只是数据模型中的一对点,那么这不会减慢你的速度。
你的性能问题是你正在重新绘制每一行被添加的东西,即O(n ^ 2)或非常具体的Schlemiel-the-Painter's algorithm。
最简单的改进,假设您在UIView的-drawRect:
内绘图,可能只会使包含新行的rect无效并重绘。根据起点和终点,你可以创建无效的矩形发送到-setNeedsDisplayInRect:
,然后在你的drawRect中,查看你所有的行,并只画出那些落在rect里面的行。这会将您的绘制性能限制为线条的大小,并且在较小的程度上,“已经存在”的绘图。