1.效果圖
Untitled3.gif
2.代碼展示
- 創(chuàng)建header file
/*
該方法負(fù)責(zé)繪制圓角矩形
x1,y2: 圓角矩形左上角的坐標(biāo)
width , height :控制圓角矩形寬高
radius 控制圓角矩形的四個(gè)圓角的半徑
*/
//void CGContextAssRoundRect(CGContextRef c, CGFloat x1, CGFloat y1, CGFloat width, CGFloat height, CGFloat radius)
//{
// //移動(dòng)到左上角
// CGContextMoveToPoint(c, x1 + radius, y1);
// //添加一條連接到右上角的線段
// CGContextAddLineToPoint(c, x1 + width - radius, y1);
// //添加一段圓弧
// CGContextAddArcToPoint(c, x1 + width, y1, x1 + width, y1 + radius, radius);
// //添加一條連接到右下角的線段
// CGContextAddLineToPoint(c, x1 + width, y1 + height - radius);
//
//}
void CGContextAddRoundRect(CGContextRef c, CGFloat x1 , CGFloat y1, CGFloat width , CGFloat height , CGFloat radius)
{
// 移動(dòng)到左上角
CGContextMoveToPoint (c, x1 + radius , y1);
// 添加一條連接到右上角的線段
CGContextAddLineToPoint(c , x1 + width - radius, y1);
// 添加一段圓弧
CGContextAddArcToPoint(c , x1 + width , y1, x1 + width
, y1 + radius, radius);
// 添加一條連接到右下角的線段
CGContextAddLineToPoint(c , x1 + width, y1 + height - radius);
// 添加一段圓弧
CGContextAddArcToPoint(c , x1 + width, y1 + height
, x1 + width - radius , y1 + height , radius);
// 添加一條連接到左下角的線段
CGContextAddLineToPoint(c , x1 + radius, y1 + height);
// 添加一段圓弧
CGContextAddArcToPoint(c , x1, y1 + height , x1
, y1 + height - radius , radius);
// 添加一條連接到左上角的線段
CGContextAddLineToPoint(c , x1 , y1 + radius);
// 添加一段圓弧
CGContextAddArcToPoint(c , x1 , y1 , x1 + radius , y1 , radius);
}
void CGContextAddStar(CGContextRef c , NSInteger n, CGFloat dx , CGFloat dy , NSInteger size)
{
CGFloat dig = 4 * M_PI / n ;
// 移動(dòng)到指定點(diǎn)
CGContextMoveToPoint(c , dx , dy + size);
for(int i = 1 ; i <= n ; i++)
{
CGFloat x = sin(i * dig);
CGFloat y = cos(i * dig);
// 繪制從當(dāng)前點(diǎn)連接到指定點(diǎn)的線條
CGContextAddLineToPoint(c , x * size + dx ,y * size + dy);
}
}
2.再創(chuàng)建一個(gè)header file
//枚舉類型
typedef enum
{
klineShape = 0,
krectShape,
kEillpseShape,
kRoundRectShape,
kPenShape
}ShapeType;
3.繼承uiview
@property (nonatomic, strong) UIColor* currentColor;
@property (nonatomic, assign) ShapeType shape;
CGPoint firstTouch, prevTouch, lastTouch;
// 定義向內(nèi)存中圖片執(zhí)行繪圖的CGContextRef
CGContextRef buffCtx;
UIImage* image;
- (id)initWithCoder:(NSCoder*)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// 初始化時(shí)將當(dāng)前顏色設(shè)為紅色
self.currentColor = [UIColor redColor];
// 創(chuàng)建內(nèi)存中的圖片
UIGraphicsBeginImageContext(self.bounds.size);
// 獲取向內(nèi)存中圖片執(zhí)行繪圖的CGContextRef
buffCtx = UIGraphicsGetCurrentContext();
}
return self;
}
// 當(dāng)用戶手指開始觸碰時(shí)激發(fā)該方法
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
// 獲取觸碰點(diǎn)坐標(biāo)
firstTouch = [touch locationInView:self];
// 如果當(dāng)前正在進(jìn)行自由繪制扇调,prevTouch代表第一個(gè)觸碰點(diǎn)
if (self.shape == kPenShape)
{
prevTouch = firstTouch;
}
}
// 當(dāng)用戶手指在控件上拖動(dòng)時(shí)不斷地激發(fā)該方法
- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
// 獲取觸碰點(diǎn)坐標(biāo)
lastTouch = [touch locationInView:self];
// 如果當(dāng)前正在進(jìn)行自由繪制
if (self.shape == kPenShape)
{
// 向內(nèi)存中的圖片執(zhí)行繪制
[self draw:buffCtx];
// 取出內(nèi)存中的圖片苟弛,保存到image中
image = UIGraphicsGetImageFromCurrentImageContext();
}
// 通知該控件重繪酌伊,此時(shí)會(huì)實(shí)時(shí)地繪制起始點(diǎn)與用戶手指拖動(dòng)點(diǎn)之間的形狀
[self setNeedsDisplay];
}
// 當(dāng)用戶手指離開控件時(shí)激發(fā)該方法
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
// 獲取離開觸碰的點(diǎn)坐標(biāo)
lastTouch = [touch locationInView:self];
// 向內(nèi)存中的圖片執(zhí)行繪制,即把最終確定圖形繪制到內(nèi)存中圖片上
[self draw:buffCtx];
image = UIGraphicsGetImageFromCurrentImageContext();
// 通知重繪。
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
// 獲取繪圖上下文
CGContextRef ctx = UIGraphicsGetCurrentContext();
// 將內(nèi)存中的圖片繪制出來
[image drawAtPoint:CGPointZero];
// 調(diào)用draw:方法執(zhí)行繪制
[self draw:ctx];
}
// 定義一個(gè)函數(shù)敦腔,用于根據(jù)firstTouch缆八、lastTouch來確定矩形區(qū)域
- (CGRect) curRect
{
return CGRectMake(firstTouch.x, firstTouch.y,
lastTouch.x - firstTouch.x ,
lastTouch.y - firstTouch.y);
}
- (void)draw:(CGContextRef)ctx
{
// 設(shè)置線條顏色
CGContextSetStrokeColorWithColor(ctx, self.currentColor.CGColor);
// 設(shè)置填充顏色
CGContextSetFillColorWithColor(ctx, self.currentColor.CGColor);
// 設(shè)置線寬
CGContextSetLineWidth(ctx, 2.0);
CGContextSetShouldAntialias(ctx, YES);
switch (self.shape) {
CGFloat leftTopX , leftTopY;
case klineShape:
// 添加從firstTouch到lastTouch的路徑
CGContextMoveToPoint(ctx, firstTouch.x, firstTouch.y);
CGContextAddLineToPoint(ctx, lastTouch.x, lastTouch.y);
// 繪制路徑
CGContextStrokePath(ctx);
break;
case krectShape:
// 填充矩形
CGContextFillRect(ctx ,[self curRect]);
break;
case kEillpseShape:
// 填充橢圓
CGContextFillEllipseInRect(ctx ,[self curRect]);
break;
case kRoundRectShape:
// 計(jì)算左上角的坐標(biāo)
leftTopX = firstTouch.x < lastTouch.x ? firstTouch.x :
lastTouch.x;
leftTopY = firstTouch.y < lastTouch.y ? firstTouch.y :
lastTouch.y;
// 添加圓角矩形的路徑
CGContextAddRoundRect(ctx ,leftTopX ,leftTopY ,
fabs(lastTouch.x - firstTouch.x) ,
fabs(lastTouch.y - firstTouch.y) , 16);
// 填充路徑
CGContextFillPath(ctx);
break;
case kPenShape:
// 添加從prevTouch到lastTouch的路徑
CGContextMoveToPoint(ctx, prevTouch.x, prevTouch.y);
CGContextAddLineToPoint(ctx, lastTouch.x, lastTouch.y);
// 繪制路徑
CGContextStrokePath(ctx);
// 使用prevTouch保存當(dāng)前點(diǎn)
prevTouch = lastTouch;
break;
}
}
@interface ViewController ()
{
NSArray *colors;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
colors = [NSArray arrayWithObjects:
[UIColor redColor],[UIColor greenColor],
[UIColor blueColor],[UIColor yellowColor],
[UIColor purpleColor],[UIColor cyanColor],
[UIColor blackColor] , nil];
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)changeColor:(UISegmentedControl *)sender {
// 根據(jù)用戶的選擇來修改FKDrawView的當(dāng)前顏色
((GSCDrawView*)self.view).currentColor = [colors objectAtIndex:sender.selectedSegmentIndex];
}
- (IBAction)changeShape:(UISegmentedControl *)sender {
// 修改FKDrawView控件的shape屬性
((GSCDrawView*)self.view).shape = sender.selectedSegmentIndex;
}