iOS:简单画板(path方式)

本文介绍了如何在iOS应用中创建一个简单的画板功能。通过在Main.storyboard中添加UIView,设置自定义视图类来处理触摸事件和绘制线条。详细步骤包括创建路径集合、监听触摸事件,以及重写drawRect方法来绘制路径。同时,文章还提到了添加清除、保存到相册的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、在Main.storyboard中拖入一个UIView,用于显示绘制的线条,将Class属性改成自定义类(此类继承UIView,处理触控事件并绘制线条),并拖三个UIButton用于处理返回上级、清空画板、保存相册的点击事件,代码如下:

#import "ViewController.h"

@interface ViewController ()
//UIView引用
@property (weak, nonatomic) IBOutlet CMHuaBan *huabanV;
//三个点击事件监听方法
- (IBAction)onBackClick:(id)sender;
- (IBAction)onClearClick:(id)sender;
- (IBAction)onSaveClick:(id)sender;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

/*
 
 */
- (IBAction)onBackClick:(id)sender {
    //调用自定义类中的自定义返回方法
    [self.huabanV back];
}

- (IBAction)onClearClick:(id)sender {
    //调用自定义类中的自定义清空方法
    [self.huabanV clear];
}

- (IBAction)onSaveClick:(id)sender {
    //调用自定义类中的自定义保存方法
    [self.huabanV save];
}
@end

二、新建自定义CMHuaBan,继承UIView,处理画板的各种拖动事件以及绘制线条:

思路:

(1)创建path的集合成员变量,用于存储每条path的值;

(2)监听touchesBegan方法(down事件),创建path,创建线的起点xy值,并设置path的一些属性;

(3)监听touchesMoved(move事件)和touchesEnded(up事件)方法,创建path的其他点;

(4)重写drawRect方法,循环绘制每一条path。

1.CMHuaBan.h代码,主要定义三个方法供外部调用,处理清空、返回、保存操作:

#import <UIKit/UIKit.h>

@interface CMHuaBan : UIView

- (void) clear;
- (void) back;
- (void) save;

@end

2.CMHuaBan.m代码如下:

#import "CMHuaBan.h"

@interface CMHuaBan()

@property (nonatomic, strong) NSMutableArray *pathList;

@end

@implementation CMHuaBan

/*
 懒加载初始化list集合
 */
- (NSMutableArray *)list{
    if(_pathList == nil){
        _pathList = [NSMutableArray array];
    }
    return _pathList;
}

/*
 UIView方法,绘制path路径
 */
- (void)drawRect:(CGRect)rect {
    //设置path的颜色
    [[UIColor redColor] set];
    //循环绘制绘制path路径
    for (UIBezierPath *path in self.pathList) {
        [path stroke];
    }
}

/*
 自定义方法,将点存入列表
 */
- (void)addPoint:(NSSet<UITouch *> *)touches isReset:(BOOL *)isReset{
    //获取UITouch
    UITouch *touch = [touches anyObject];
    //获取当前点的值CGPoint
    CGPoint point = [touch locationInView:touch.view];
    
    UIBezierPath *path = nil;
    if(isReset){//如果是按下,则新建一个列表存放新的path集合
        path = [UIBezierPath bezierPath];
        //设置线宽
        path.lineWidth = 10;
        //设置线头圆角
        path.lineCapStyle = kCGLineCapRound;
        path.lineJoinStyle = kCGLineJoinRound;
        //创建path的起点
        [path moveToPoint:point];
        
        [self.pathList addObject:path];
    } else {//移动与松开时,获取最后一个列表
        path = [self.pathList lastObject];
        //创建path的其他点
        [path addLineToPoint:point];
    }
    
    //刷新,触发drawRect绘制
    [self setNeedsDisplay];
}

/*
 UIView方法,按下手指时触发
 */
- (void) touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    if(self.pathList == nil){
        self.pathList = [NSMutableArray array];
    }
    //调用自定义方法,将path存入列表
    [self addPoint:touches isReset:YES];
}
/*
 UIView方法,拖动手指时触发
 */
- (void) touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //调用自定义方法,将path存入列表
    [self addPoint:touches isReset:NO];
}
/*
 UIView方法,松开手指时触发
 */
- (void) touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //调用自定义方法,将path存入列表
    [self addPoint:touches isReset:NO];
}

/*
 清空画板
 */
- (void) clear{
    if([self.pathList count] == 0){
        return;
    }
    //清空path列表
    [self.pathList removeAllObjects];
    //重绘
    [self setNeedsDisplay];
}
/*
 返回上一次绘制
 */
- (void) back{
    if([self.pathList count] == 0){
        return;
    }
    //删除最后一个path列表
    [self.pathList removeLastObject];
    //重绘
    [self setNeedsDisplay];
}
/*
 截图保存
 */
- (void) save{
    if([self.pathList count] == 0){
        return;
    }
    /*
     将当前View截图
     */
    //开启上下文
    UIGraphicsBeginImageContextWithOptions(self.frame.size, NO, 0.0);
    //将当前View的layer渲染到上下文
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    
    //取出图片
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    
    //结束上下文
    UIGraphicsEndImageContext();
    
    //保存图片到相册
    UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    
}
/*
 保存相册回调方法
 */
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{
    if(error){
        NSLog(@"保存失败");
    } else {
        NSLog(@"保存成功");
    }
}

@end

三、打开Info.plist文件,在"<dict>"节点的末尾添加写相册的权限:

<dict>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>请求获取读取媒体资料库的权限</string>
<dict>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值