详解iOS App中图片的线段涂鸦功能的添加方法_IOS

接下来我们要讲图片的涂鸦,我们分开一点一点拓展,先给图片上划线
创建项目 起名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); 

以上方法的思路 就是在线段画完之后 确定三个点 画一个三角形作为箭头形状

时间: 2024-09-21 21:58:34

详解iOS App中图片的线段涂鸦功能的添加方法_IOS的相关文章

详解iOS开发中UITableview cell 顶部空白的多种设置方法_IOS

我知道没人会主动设置这个东西,但是大家一定都遇到过这个问题,下面总结下可能是哪些情况: 1, self.automaticallyAdjustsScrollViewInsets = NO; 这个应该是最常见而且不容易被发现的原因,起因是iOS7在Conttoller中新增了automaticallyAdjustsScrollViewInsets这个属性,当设置为YES时(默认YES),如果视图里面存在唯一一个UIScrollView或其子类View,那么它会自动设置相应的内边距,这样可以让scr

详解iOS App中UITableView的创建与内容刷新_IOS

UITableView几乎是iOS开发中用处最广的一个控件,当然也是要记相当多东西的一个控件. 创建首先创建一个新的项目,并添加一个MainViewController的Class文件 打开MainViewController.h文件 @interface MainViewController : UIViewController<UITableViewDataSource,UITableViewDelegate> @property (nonatomic, retain) NSArray *

详解iOS App中UiTabBarController组件的基本用法_IOS

UiTabBarController这个控制器绝对是项目架构时做常用的一个控件. 我们大致看下控件的效果,我们就知道为什么说他常见了. 这就是最简单的一个雏形,想必现在基本70%的应用界面结构都会是这样的. 在Android中我们以ActivityGroup或是现在的fragment来实现,一个容器中包含多个子控制器. 下面我们还是以建立xib文件的形式来实现一个这样的整体布局的例子. 当然在 xcode中我们会发现其实直接有这么一个模板了 但是直接使用模板后会发现是直接在代码里实现了子布局得添

详解iOS App中调用AVAudioPlayer播放音频文件的用法_IOS

要给工程中添加音频,首先要导入音频的框架 AVFoundation.framework 然后新建一个类继承于UIViewController, 我这里就叫FirstVC. 首先在 AppDelegate.m中初始化根视图 复制代码 代码如下: #import "AppDelegate.h" #import "FirstVC.h" @implementation AppDelegate - (void)dealloc {     [_window release];

详解iOS App中UIPickerView滚动选择栏的添加方法_IOS

1.UIPickerView的宽度和高度是固定的,纵向是320216,横向是568162 2.属性: 复制代码 代码如下: @property(nonatomic,readonly)NSInteger numberOfComponents; // 选择框的行数 @property(nonatomic,assign)idUIPickerViewDataSource> dataSource; (类似于UITableView) @property(nonatomic,assign)idUIPicker

详解iOS App中UISwitch开关组件的基本创建及使用方法_IOS

一.第一种创建UISwitch组件的方法,在代码中动态创建. 1.打开Xcode, 新建项目Switch,选择Single View Application. 2.打开ViewController.m文件在viewDidLoad方法里添加代码: 复制代码 代码如下: (void)viewDidLoad  {      [super viewDidLoad];      UISwitch *switchButton = [[UISwitch alloc] initWithFrame:CGRectM

问题就是啊啊-iOS app中怎么实现发红包功能

问题描述 iOS app中怎么实现发红包功能 求大神指导啊啊啊啊,公司最新的想法,现在还不知道恩么弄,有时候uiszhidao的的啊真希望不要哈哈哈发 你那么大开发建设的飞机哦圣诞节发来撒可对方能卡死的叫法开始的缴费卡拉斯的减肥你看拉水泥的反馈暗示对方的大师傅 解决方案 app 评论功能实现ios开发之APP升级的实现iOS App运行在后台实现定位以及播放音频功能 解决方案二: 不就是集成一个支付功能吗?UI方面想怎么设计都可以啊

iOS缓存文件大小显示功能和一键清理功能的实现方法_IOS

缓存占用了系统的大量空间,如何实时动态的显示缓存的大小,使用户清晰的了解缓存的积累情况,有效的进行一键清理呢? 为方便读者和未来自己更好理解,我们创建这样场景.(在表视图的清除缓存一单元格内创建一个UILabel *cacheLabel用于显示当前缓存,当点击单元格弹出提示框,点击确定,清除缓存). 下面是实现代码: #pragma mark - 计算缓存大小 - (NSString *)getCacheSize { //定义变量存储总的缓存大小 long long sumSize = 0; /

详解iOS App设计模式开发中对于享元模式的运用_IOS

享元模式的概念 在面向对象软件设计中,利用公共对象不仅能节省资源还能提高性能.共享的对象只能提供某些内在的信息,而不能用来识别对象.专门用于设计可共享对象的一种设计模式叫做享元模式(Flyweight pattern). 实现享元模式需要两个关键组件,通常是可共享的享元对象和保存他们的池.某种中央对象维护这个池,并从它返回适当的实例. 运用共享技术有效地支持大量细粒度的对象. 公共交通(如公共汽车)已有一百多年的历史了.大量去往相同方向的乘客可以分担保有和经营车辆(如公共汽车)的费用.公共汽车有