小画板demo

    用storyBoard搭界面,最上面用到了一个toolBar ,中间用到了一个View,用来画东西,最下面在放一个View,用来存放三个按钮和一个UISlider

接下来就可以开始你的大作了,首先因为要在第二个拖的控件蓝色的View里画东西,所以要自定义一个类,

@property(nonatomic,strong)UIBezierPath *connectPath;

@end

@implementation LSdrawView

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    UITouch *touch = touches.anyObject;

    CGPoint loc = [touch locationInView:touch.view];

   

    UIBezierPath *path = [UIBezierPath bezierPath];

    self.connectPath = path;

    [path moveToPoint:loc];

    [self setNeedsDisplay];

}

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    UITouch *touch = touches.anyObject;

    CGPoint loc = [touch locationInView:touch.view];

    

    

    [self.connectPath addLineToPoint:loc];

    [self setNeedsDisplay];

}

-(void)drawRect:(CGRect)rect{

    [self.connectPath stroke];

}

这段代码是第一步的到触摸的点然后,接线,在这里两个注意点,首先我们要接线创建一个UIBezierpath的路径去接收接线,第二我们要在DrawRect方法里进行渲染,第三个,你在View里想要显示线条就必须进行重绘,这是单线的做法


@interface LSdrawView()

@property(nonatomic,strong)UIBezierPath *connectPath;

@property(nonatomic,strong)NSMutableArray *connectArray;

@end

@implementation LSdrawView

-(NSMutableArray *)connectArray{

    if (!_connectArray) {

        _connectArray = [NSMutableArray array];

    }

    return _connectArray;

}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    UITouch *touch = touches.anyObject;

    CGPoint loc = [touch locationInView:touch.view];

   

    UIBezierPath *path = [UIBezierPath bezierPath];

    [self.connectArray addObject:path];

    [path moveToPoint:loc];

    [self setNeedsDisplay];

}

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    UITouch *touch = touches.anyObject;

    CGPoint loc = [touch locationInView:touch.view];

    

    

    [[self.connectArray lastObject] addLineToPoint:loc];

    [self setNeedsDisplay];

}

-(void)drawRect:(CGRect)rect{

    for (UIBezierPath *path in self.connectArray) {

      [path stroke];

    }

    

}

这是多线处理,与多线的区别舍弃使用connectPath,新创建一个可变数组去存放画好的线,有几个注意点 首先数组里得先存放刚接触屏幕的首路径,然后在移动屏幕的时候使用可变数组中最后一个元素去添加添加新的线条,最后在渲染中使用for循环可变数组中的路径进行渲染


接下来设置线宽。。。

@interface ViewController ()

@property (weak, nonatomic) IBOutlet LSdrawView *myDrawView;

@property (weak, nonatomic) IBOutlet UISlider *mySlider;


@end


@implementation ViewController

- (IBAction)mySlider:(UISlider *)sender {

    self.myDrawView.lineWidth = sender.value;

}


- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view, typically from a nib.

    self.myDrawView.lineWidth = self.mySlider.value;

}


- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}


@end


首先在控制器的.m文件中给Slider拖一根Action,我们要设置画板中的线宽,所以需要将故事板中的第二个View控件拖一根OutLet线,然后获取里面的线宽,可是线宽在View里是私有的,所以。。。下一步

#import <UIKit/UIKit.h>


@interface LSdrawView : UIView

@property(nonatomic,assign)CGFloat lineWidth;

@end

在自定义的类中设置一个线宽,因为.m中的属性是私有的

获取到线宽之后,然后进行设置,注意要改slider的类型,按钮不能传id不然没有value转换的,接下来在View中改变线宽



@interface LSdrawView()

@property(nonatomic,strong)UIBezierPath *connectPath;

@property(nonatomic,strong)NSMutableArray *connectArray;

@end

@implementation LSdrawView

-(NSMutableArray *)connectArray{

    if (!_connectArray) {

        _connectArray = [NSMutableArray array];

    }

    return _connectArray;

}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    UITouch *touch = touches.anyObject;

    CGPoint loc = [touch locationInView:touch.view];

   

    UIBezierPath *path = [UIBezierPath bezierPath];

    path.lineWidth  =self.lineWidth;//单独设置线宽

    [self.connectArray addObject:path];

    [path moveToPoint:loc];

    [self setNeedsDisplay];

}

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    UITouch *touch = touches.anyObject;

    CGPoint loc = [touch locationInView:touch.view];

    

    

    [[self.connectArray lastObject] addLineToPoint:loc];

    [self setNeedsDisplay];

}

-(void)drawRect:(CGRect)rect{

    for (UIBezierPath *path in self.connectArray) {

//        path.lineWidth = self.lineWidth;//不能统一设置线宽,会出现一条线改变多条线改变

      [path stroke];

    }

    

}

在这里设置线宽,首先不能直接在drawRect方法里直接在for循环中设置线宽,会导致一变都变的情况,我们要在toughBegan方法中,单独设置线宽,接下来虽然实现了功能可使没有设置默认线宽,所以我们拖一根Slider属性线,然后在ViewDidLoad里设置默认线宽



设置颜色和线宽一个道理,给三个颜色的Button都拖到同一个点击事件,拿不到View中的颜色,所以在View的.h中声明颜色的成员属性,注意在View中设置颜色的时候,path没有自身的颜色属性,我们需要创建一个继承自UIBezierPath的类,然后设置里面的成员属性线的颜色,然后在path中重新设置线的颜色

@implementation LSdrawView

-(NSMutableArray *)connectArray{

    if (!_connectArray) {

        _connectArray = [NSMutableArray array];

    }

    return _connectArray;

}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    UITouch *touch = touches.anyObject;

    CGPoint loc = [touch locationInView:touch.view];

   

    LSlineColor *path = [LSlineColor bezierPath];

    

    path.lineColor = self.lineColor;

    

    path.lineWidth  =self.lineWidth;//单独设置线宽

    [self.connectArray addObject:path];

    [path moveToPoint:loc];

    [self setNeedsDisplay];

}

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    UITouch *touch = touches.anyObject;

    CGPoint loc = [touch locationInView:touch.view];

    

    

    [[self.connectArray lastObject] addLineToPoint:loc];

    [self setNeedsDisplay];

}

-(void)drawRect:(CGRect)rect{

    for (LSlineColor *path in self.connectArray) {

//        path.lineWidth = self.lineWidth;//不能统一设置线宽,会出现一条线改变多条线改变

//        [self.lineColor set];//不能统一设置颜色,会导致一变多变

        [path.lineColor set];//设置线的颜色

      [path stroke];

    }

    

}



最后设置工具栏上的四个方法

- (IBAction)mySlider:(UISlider *)sender {

    self.myDrawView.lineWidth = sender.value;

}


- (IBAction)colorButton:(UIButton *)sender {

    

    self.myDrawView.lineColor = sender.backgroundColor;

}

- (IBAction)clearButton:(UIBarButtonItem *)sender {

    

    [self.myDrawView.connectArray removeAllObjects];

    [self.myDrawView setNeedsDisplay];

    

}

- (IBAction)backButton:(UIBarButtonItem *)sender {

    

    [self.myDrawView.connectArray removeLastObject];

    [self.myDrawView setNeedsDisplay];

    

}

- (IBAction)eraserButton:(UIBarButtonItem *)sender {

    

//    LSlineColor *path = [LSlineColor bezierPath];

    path.lineColor = self.myDrawView.backgroundColor;//这个方法不可以

//    self.myDrawView.lineColor = self.myDrawView.backgroundColor;

//    [self.myDrawView.connectArray addObject:path];

    

    //还可以用下面的方法

    self.myDrawView.lineColor = self.myDrawView.backgroundColor;

    [self.myDrawView setNeedsDisplay];

    

}

- (IBAction)saveButton:(UIBarButtonItem *)sender {

    

    UIGraphicsBeginImageContextWithOptions(self.myDrawView.frame.size, YES, 0.0);

    

    CGContextRef ctx = UIGraphicsGetCurrentContext();

    

    [self.myDrawView.layer renderInContext:ctx];

    

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    

    UIGraphicsEndImageContext();

    

    UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);

    

}


使用橡皮擦功能的时候,注意如果你用path绘制路径,设置背景色,在View的可变数组里添加这个绘制的路径会发生没有变化,是因为你要改的是self.lineColor的颜色,而不是path路径的颜色,之后还会有个小BUG,点击回退的时候有一条路径是,你之前添加的一条和背景色一样的路径,先回退的这个路径始终在我的集合里面,回退的时候这个集合也要回退一次,这个路径适合背景一模一样的颜色,是存在的,所以提供一个更加好的方式,如上面代码。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值