我在过去5个月里使用的是目标c。所以现在我愿意 喜欢制作一个用户能够通过交互绘制大量线条的应用程序(例如手指滑动)。
所以我开始使用drawrect方法和Core图形库。所以我创建了一个包含CGPoints的数组,并且在调用[self setNeedsDisplay]时,appi从头开始重新绘制整个屏幕(for draw in drawrect-因为我需要在TouchesMoved中手指移动时绘制和擦除线条的能力)。当阵列超过例如1000行时,就会出现问题,因为响应速度很慢。
除了寻求更好的性能之外,我还提出了一些方法来绘制视图中的每一行,然后添加此视图(使用CGBitmapContextCreate,uiimageview),(对于TouchesMOved,appi正在删除上一个视图并添加新视图时间)。
不幸的是结果是一样的。添加更多和更多的表现是糟糕的。画布上的更多上下文(线条,形状等)。
如果你回答这个问题,我将不胜感激。 哪种技术最适合在画布上画出大量的线条? Cocos 2d是一个选择吗? Open gl是我的最后一个选择,我更喜欢在coreGraphics库附近的解决方案。有没有办法使用核心图形在绘制第一行和绘制第1000行时具有相同的性能?
对不起我的英文.. :(
更新15/06/12 下面是代码。我在这篇文章中使用了Dimitris的一些想法:
Drawing incrementally in a UIView (iPhone)
- (BOOL) initContext:(CGSize)size {
int bitmapByteCount;
int bitmapBytesPerRow;
bitmapBytesPerRow = (size.width * 4);
bitmapByteCount = (bitmapBytesPerRow * size.height);
cacheBitmap = malloc( bitmapByteCount );
cacheBitmapSwiped= malloc( bitmapByteCount );
ctx = CGBitmapContextCreate (cacheBitmap, size.width, size.height, 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst);
//for finger sweaping
cacheContextSwiped = CGBitmapContextCreate (cacheBitmapSwiped, size.width, size.height, 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst);
return YES;
}
//method which draw a line on TouchesEND action
- (void) drawLine:(id)sender {
UIColor *color = [UIColor colorWithRed:0.0 green:0.0 blue:1.0 alpha:1.0];
CGContextSetStrokeColorWithColor(ctx, [color CGColor]);
CGContextSetLineWidth(ctx, 4);
//outArray:array which holds cgpoints
if ([outArray count] > 0)
{
CGPoint point1 = [(NSValue *)[[outArray objectAtIndex:[outArray count] -1 ] objectAtIndex: 0] CGPointValue];
CGPoint point2 = [(NSValue *)[[outArray objectAtIndex:[outArray count] -1 ] objectAtIndex: 1] CGPointValue];
///ADDON
CGRect rectPoint1 = CGRectMake(point1.x-10, point1.y-10, 20, 20);
CGRect rectPoint2 = CGRectMake(point2.x-10, point2.y-10, 20, 20);
CGRect newRect = CGRectUnion(rectPoint1, rectPoint2);
///ADD NEW CHECK
if (CGRectContainsPoint(newRect, point1) && CGRectContainsPoint(newRect, point2)) {
CGContextMoveToPoint(ctx, point1.x, point1.y);
CGContextAddLineToPoint(ctx, point2.x, point2.y);
CGContextStrokePath(ctx);
}
[self setNeedsDisplayInRect:newRect];
}
}
//method which draws lines on TouchesMoved action
//draw in rect
-(void)drawLineSwiped:(id)sender{
//size of main image RECT
CGSize mainImageRectSize = mainImageRect.size;
int bitmapByteCount;
int bitmapBytesPerRow;
// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow = (mainImageRectSize.width * 4);
bitmapByteCount = (bitmapBytesPerRow * mainImageRectSize.height);
// Allocate memory for image data. This is the destination in memory
// where any drawing to the bitmap context will be rendered.
//bitmap data
//bitmap data for finger sweaped
cacheBitmapSwiped= malloc( bitmapByteCount );
//for finger sweaping
cacheContextSwiped = CGBitmapContextCreate (cacheBitmapSwiped, mainImageRectSize.width, mainImageRectSize.height, 8, bitmapBytesPerRow, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst);
UIColor *color = [UIColor colorWithRed:0.0 green:0 blue:1.0 alpha:1.0];
CGContextSetStrokeColorWithColor(cacheContextSwiped, [color CGColor]);
CGContextSetLineWidth(cacheContextSwiped, 2);
if ([outArray count] > 0)
{
CGPoint point1 = [(NSValue *)[[outArray objectAtIndex:[outArray count] -1 ] objectAtIndex: 0] CGPointValue];
CGPoint point2 = [(NSValue *)[[outArray objectAtIndex:[outArray count] -1 ] objectAtIndex: 1] CGPointValue];
CGRect rectPoint1 = CGRectMake(point1.x-10, point1.y-10, 20, 20);
CGRect rectPoint2 = CGRectMake(point2.x-10, point2.y-10, 20, 20);
CGRect newRect = CGRectUnion(rectPoint1, rectPoint2);
if (CGRectContainsPoint(newRect, lastPoint1) && CGRectContainsPoint(newRect, newPoint)) {
//draw line into the screen
CGContextMoveToPoint(cacheContextSwiped, point1.x, point1.y);
CGContextAddLineToPoint(cacheContextSwiped, point2.x, point2.y);
CGContextStrokePath(cacheContextSwiped);
}
free(cacheBitmapSwiped);
[self setNeedsDisplayInRect:newRect];
}
}
- (void)drawRect:(CGRect)rect {
context = UIGraphicsGetCurrentContext();
if (mouseEnded) {
CGImageRef cacheImage;
cacheImage= CGBitmapContextCreateImage(ctx);
CGContextDrawImage(context, self.bounds, cacheImage);
CGImageRelease(cacheImage);
}
else if(mouseSwiped ){
CGImageRef cacheImageSwiped;
cacheImageSwiped= CGBitmapContextCreateImage(cacheContextSwiped);
CGContextDrawImage(context, self.bounds, cacheImageSwiped);
CGImageRelease(cacheImageSwiped);
}
另外我必须说我有一个方法(在outArray中添加cgpoints),它在TouchesBegan,TouchesMoved,TouchesEnded中运行。
所以我试图在手指的移动过程中绘制一条线(在移动过程中也移除了前一条线),但是底层(或之前的线条)从我的屏幕上消失了。我还尝试在手指移动期间添加子视图(在此模型中)并同时删除先前的子视图,但也会在应用程序中添加延迟。
到目前为止,绘画的情况对我来说太困惑了。在android中,是一个绘制(onDraw)的方法,此方法更新视图,不会覆盖它(使用invalidate()调用)。 你有什么建议吗?我必须重申,我想绘制第1200行,没有(光学)延迟,具有良好的性能。 感谢名单
答案 0 :(得分:0)
您应该做的第一个优化是仅重绘需要更新的区域。而不是setNeedsDisplay
中的touchesMoved:withEvent:
,而是计算您需要更新的区域(基本上是包含最后两个触摸位置的矩形),并使用此区域调用setNeedsDisplayInRect:
。
然后,在for
的{{1}}循环中,确定是否有任何给定的形状落入此矩形,只有在它被绘制时才会绘制。