最近的一个项目是与画画相关的 在这里简单总结下UIView的绘画方面的东西吧
首先必须写的方法肯定是drawRect,但是我们在代码中并不会直接去调用这个方法,因为这个方法是UIView在重绘的时候,自己调用的.
我们可以在代码中通过调用 setNeedsDisplayInRect 来强制View刷新.
下面说一下怎么在View上面画线,首先是要在响应用户在屏幕上滑动过程的三个方法
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
previousPoint1 = [touch locationInView:self];
previousPoint2 = [touch locationInView:self];
currentPoint = [touch locationInView:self];
//NSLog(@"pre %f %f",currentPoint.x,currentPoint.y);
[bufferArray removeAllObjects];
[self touchesMoved:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
previousPoint2 = previousPoint1;
previousPoint1 = currentPoint;
currentPoint = [touch locationInView:self];
if(drawStep == REDO || drawStep == UNDO)
{
if(isDraw)
drawStep = DRAW;
else
drawStep = ERASE;
}
[self calculateMinImageArea:previousPoint1 :previousPoint2 :currentPoint];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UIGraphicsBeginImageContext(self.bounds.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
curImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSDictionary *lineInfo = [NSDictionary dictionaryWithObjectsAndKeys:curImage, @"IMAGE",
nil];
if(lineArray.count == 20)
{
[lineArray removeObjectAtIndex:0];
}
[lineArray addObject:lineInfo];
}
- (void) calculateMinImageArea:(CGPoint)pp1 :(CGPoint)pp2 :(CGPoint)cp
{
// calculate mid point
CGPoint mid1 = midPoint(pp1, pp2);
CGPoint mid2 = midPoint(cp, pp1);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, mid1.x, mid1.y);
CGPathAddQuadCurveToPoint(path, NULL, pp1.x, pp1.y, mid2.x, mid2.y);
CGRect bounds = CGPathGetBoundingBox(path);
CGPathRelease(path);
CGRect drawBox = bounds;
//Pad our values so the bounding box respects our line width
drawBox.origin.x -= self.lineWidth * 1;
drawBox.origin.y -= self.lineWidth * 1;
drawBox.size.width += self.lineWidth * 2;
drawBox.size.height += self.lineWidth * 2;
UIGraphicsBeginImageContext(drawBox.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
curImage = UIGraphicsGetImageFromCurrentImageContext();
//[curImage retain];
UIGraphicsEndImageContext();
[self setNeedsDisplayInRect:drawBox];
//http://stackoverflow.com/a/4766028/489594
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate date]];
}
- (void)drawRect:(CGRect)rect
{
switch (drawStep) {
case DRAW:
{
[curImage drawAtPoint:CGPointMake(0, 0)];
CGPoint mid1 = midPoint(previousPoint1, previousPoint2);
CGPoint mid2 = midPoint(currentPoint, previousPoint1);
CGContextRef context = UIGraphicsGetCurrentContext();
[self.layer renderInContext:context];
CGContextMoveToPoint(context, mid1.x, mid1.y);
CGContextAddQuadCurveToPoint(context, previousPoint1.x, previousPoint1.y, mid2.x, mid2.y);
if(previousPoint1.x == previousPoint2.x && previousPoint1.y == previousPoint2.y && previousPoint1.x == currentPoint.x && previousPoint1.y == currentPoint.y)
{
CGContextSetLineCap(context, kCGLineCapRound);
}
else
{
CGContextSetLineCap(context, kCGLineCapRound);
}
CGContextSetLineWidth(context, self.lineWidth);
CGContextSetStrokeColorWithColor(context, self.lineColor.CGColor);
CGContextSetAlpha(context, self.lineAlpha);
CGContextStrokePath(context);
[super drawRect:rect];
//[curImage release];
break;
}
}
上面就是画线的代码片段 最基本的步骤就是 在move的时候 需要创建CGMutablePathRef 来保存移动的路径 并且调用下面这段代码来将当前的画面保存在curImg变量中,但是这个时候还看不到,因为View并没有刷新 在调用了 setNeedsDisplay之后 需要对curImg进行绘制 让用户看到刷新后的View
UIGraphicsBeginImageContext(drawBox.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
curImage = UIGraphicsGetImageFromCurrentImageContext();
//[curImage retain];
UIGraphicsEndImageContext();
上面这段代码 可以看作是截图功能,在很多地方都可以用
好困 暂时没兴趣写了