详解iOS App中图片的线段涂鸦功能的添加方法
程序员文章站
2023-12-04 20:58:22
接下来我们要讲图片的涂鸦,我们分开一点一点拓展,先给图片上划线
创建项目 起名testaddline
接下来我们在默认生成的viewcontroller中添...
接下来我们要讲图片的涂鸦,我们分开一点一点拓展,先给图片上划线
创建项目 起名testaddline
接下来我们在默认生成的viewcontroller中添加一张图片 待用
同时添加一个按钮
复制代码 代码如下:
- (void)viewdidload {
[super viewdidload];
// do any additional setup after loading the view, typically from a nib.
uiimageview *imagev = [[uiimageview alloc]initwithframe:cgrectmake(10, 120, screen_width-20, screen_height-150)];
imagev.image = [uiimage imagenamed:@"640-960-1.jpg"];
[self.view addsubview:imagev];
uibutton *testbtn = [[uibutton alloc]initwithframe:cgrectmake(screen_width/2.0-60, 60, 120, 36)];
[testbtn settitlecolor:[uicolor blackcolor] forstate:uicontrolstatenormal];
[testbtn settitle:@"添加直线" forstate:uicontrolstatenormal];
[testbtn addtarget:self action:@selector(addlineact:) forcontrolevents:uicontroleventtouchupinside];
[self.view addsubview:testbtn];
}
- (void)addlineact:(id)sender{
nslog(@"测试按钮");
}
接下来我们创建一个uiview 用来添加直线 起名:drawline
创建几个变量
复制代码 代码如下:
@property(nonatomic,strong) nsmutablearray * completelines; //已经画好的线条 存入数组
@property(nonatomic,strong) nsmutabledictionary* linesinproscess; //正在画的线条 存入字典
@property(nonatomic,strong) uicolor *linecolor;//线条颜色
@property (nonatomic)float linewidth;//线条的粗细
初始化drawline
复制代码 代码如下:
//初始化
- (id)initwithframe:(cgrect)frame{
if (self = [super initwithframe:frame]) {
//初始化变量
_completelines = [[nsmutablearray alloc]init];
_linesinproscess = [[nsmutabledictionary alloc]init];
//设置透明背景
self.backgroundcolor = [uicolor clearcolor];
}
return self;
}
我们把线条单独抽象出来 创建一个类 创建对象 起名 line
线条 两个属性 起始点 结束点(这就是数学中的两点确定一条直线)
给line 类创建两个属性
复制代码 代码如下:
#import <foundation/foundation.h>
#import <uikit/uikit.h>
@interface line : nsobject
@property(nonatomic)cgpoint begin; //线条开始点
@property(nonatomic)cgpoint end; //线条结束点
@end
接下来 我们重写drawline 的 drawrect 方法 绘制线条
复制代码 代码如下:
// only override drawrect: if you perform custom drawing.
// an empty implementation adversely affects performance during animation.
- (void)drawrect:(cgrect)rect {
// drawing code
//获取上下文
cgcontextref cgt=uigraphicsgetcurrentcontext();
//设置线条宽度
cgcontextsetlinewidth(cgt, self.linewidth);
//设置线条两端形状为圆角
cgcontextsetlinecap(cgt, kcglinecapround);
//设置颜色
[self.linecolor set];
//绘制已经完成的线段
for (line *line in _completelines){
cgcontextmovetopoint(cgt, [line begin].x, [line begin].y);
cgcontextaddlinetopoint(cgt, [line end].x, [line end].y );
cgcontextstrokepath(cgt);
}
//绘制正在画的线段
for (nsarray *v in _linesinproscess) {
line *line =[_linesinproscess objectforkey:v];
cgcontextmovetopoint(cgt, [line begin].x, [line begin].y);
cgcontextaddlinetopoint(cgt, [line end].x, [line end].y );
cgcontextstrokepath(cgt);
}
}
实现几个手指滑动方法 用来接受手指的位置画线
复制代码 代码如下:
//清空画板
-(void)clearall
{
[_completelines removelastobject];
[_linesinproscess removeallobjects];
[self setneedsdisplay];
}
-(void)touchesbegan:(nsset *)touches withevent:(uievent *)event
{
//判断是否连按
for (uitouch *t in touches) {
if ([t tapcount]>1) {
//第二次画线时第一条线还未完成时结束画线
[self clearall];
return;
}
//nsvalue 作为键使用
nsvalue *key=[nsvalue valuewithnonretainedobject:t];
// 根据触摸位置创建line对象
cgpoint loc=[t locationinview:self];
line *newline=[[line alloc]init ];
newline.begin=loc;
newline.end=loc;
//将当前正在画的线存入字典
[_linesinproscess setobject:newline forkey:key];
}
}
-(void)touchesmoved:(nsset *)touches withevent:(uievent *)event
{
//手指移动过程中按照当前手指的位置动态更新线条
for (uitouch * t in touches) {
nsvalue *key=[nsvalue valuewithnonretainedobject:t];
// 找对象当前uitouch对象的line对象
line *line =[_linesinproscess objectforkey:key];
cgpoint loc=[t locationinview:self];
line.end=loc;
}
[self setneedsdisplay];
}
-(void)endtouches:(nsset *) touches
{
//画线完成之后将当前线条加入_completelines 数组中 同时删除字典_linesinproscess里的线条
for (uitouch *t in touches) {
nsvalue *key=[nsvalue valuewithnonretainedobject:t];
line *line =[_linesinproscess objectforkey:key];
if (line) {
[_completelines addobject:line];
[_linesinproscess removeobjectforkey:key];
}
}
[self setneedsdisplay];
}
-(void)touchescancelled:(nsset *)touches withevent:(uievent *)event
{
[self endtouches:touches];
}
-(void)touchesended:(nsset *)touches withevent:(uievent *)event
{
[self endtouches:touches];
}
回到 viewcontroller中 给按钮点击事件中 添加drawline到imageview上
复制代码 代码如下:
- (void)addlineact:(id)sender{
nslog(@"测试按钮");
drawline *touchdrawview = [[drawline alloc]initwithframe:imagev.frame];
touchdrawview.linecolor = [uicolor yellowcolor];
touchdrawview.linewidth = 5.0;
touchdrawview.tag = 902;
[self.view addsubview:touchdrawview];
}
好了 运行程序试试
点击 添加直线 按钮之后 试试在图片上画线
带剪头的线条
在上面例子的基础上稍微拓展一下,给线段末尾加上一个箭头
给drawline 类中添的方法 drawrect 中添加一段代码
复制代码 代码如下:
//添加剪头
double r = sqrt((line.end.x-line.begin.x)*(line.end.x-line.begin.x)+(line.begin.y-line.end.y)*(line.begin.y-line.end.y));//线条长度
cgcontextmovetopoint(cgt,line.end.x,line.end.y);
//p1
cgcontextaddlinetopoint(cgt,line.end.x-(10*(line.begin.y-line.end.y)/r),line.end.y-(10*(line.end.x-line.begin.x)/r));
//p3
cgcontextaddlinetopoint(cgt,line.end.x+(20*(line.end.x-line.begin.x)/r), line.end.y-(20*(line.begin.y-line.end.y)/r));
//p2
cgcontextaddlinetopoint(cgt,line.end.x+(10*(line.begin.y-line.end.y)/r),line.end.y+(10*(line.end.x-line.begin.x)/r));
cgcontextaddlinetopoint(cgt, line.end.x,line.end.y);
cgcontextdrawpath(cgt,kcgpathfillstroke);
cgcontextstrokepath(cgt);
以上方法的思路 就是在线段画完之后 确定三个点 画一个三角形作为箭头形状
上一篇: IOS多线程实现多图片下载(二)
推荐阅读
-
详解iOS App中UISwitch开关组件的基本创建及使用方法
-
详解iOS App中UIPickerView滚动选择栏的添加方法
-
详解iOS App开发中改变UIButton内部控件的基本方法
-
详解在iOS App中自定义和隐藏状态栏的方法
-
详解iOS App开发中UIViewController的loadView方法使用
-
iOS App中调用相册中图片及获取最近的一张图片的方法
-
详解iOS App中图片的线段涂鸦功能的添加方法
-
详解iOS App开发中改变UIButton内部控件的基本方法
-
详解在iOS App中自定义和隐藏状态栏的方法
-
详解iOS App开发中UIViewController的loadView方法使用