CAShapeLayer画板

作者: Acthink | 来源:发表于2016-08-30 18:09 被阅读137次

    参考:CAShapeLayer - 绘图板

    由于参考的文章代码的线条是写死的,所有对于画板的需求来说,还是不太好用,所以自己写了个Demo
    直接上代码了:
    <code>

     @interface ViewController ()
    
     @property (nonatomic, strong, nullable) NSMutableArray * drawPaths;
     @property (nonatomic, strong, nullable) NSMutableArray * drawLayers;
    
     @end
    
     @implementation ViewController
    
    - (void)viewDidLoad {
            [super viewDidLoad];
            UIButton * clearBtn = [[UIButton alloc]
              initWithFrame:CGRectMake(self.view.bounds.size.width - 100, 44, 100, 50)];
            clearBtn.backgroundColor = [UIColor grayColor];
            [clearBtn setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
            [clearBtn setTitle:@"clear" forState:UIControlStateNormal];
            clearBtn.tag = 1;
            [clearBtn addTarget:self action:@selector(backOrClear:) forControlEvents:UIControlEventTouchUpInside];
            [self.view addSubview: clearBtn];
            UIButton * backBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 44, 100, 50)];
            backBtn.backgroundColor = [UIColor grayColor];
            [backBtn setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
            [backBtn setTitle:@"back" forState:UIControlStateNormal];backBtn.tag = 2;
            [backBtn addTarget:self action:@selector(backOrClear:) forControlEvents:UIControlEventTouchUpInside];
            [self.view addSubview: backBtn];
      }
      - (void)backOrClear:(UIButton *)sender{
            switch (sender.tag) {
                  case 1:{
                        for (CAShapeLayer * layer in self.drawLayers) {
                              [layer removeFromSuperlayer];
                        }
                        self.drawLayers = nil;
                        [self.drawPaths removeAllObjects];
                  }
                  break;
                  default:{
                        CAShapeLayer * layer = self.drawLayers.lastObject;
                        [layer removeFromSuperlayer];
                        [self.drawLayers removeLastObject];
                  }
                  break;
            }
      }
      - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ 
              [super touchesBegan:touches withEvent:event]; 
              UIBezierPath * path = [UIBezierPath bezierPath];  
              [path moveToPoint:[[touches anyObject] locationInView:self.view]];   
              CAShapeLayer *layer = [CAShapeLayer layer];    
              layer.backgroundColor = [UIColor clearColor].CGColor;  
              layer.frame = self.view.bounds;  
              layer.path = path.CGPath;   
              layer.lineWidth = 3.0f;   
              layer.strokeColor = [UIColor redColor].CGColor;  
              layer.miterLimit = 2.;   
              layer.lineDashPhase = 10;   
              layer.lineDashPattern = @[@1,@0];   
              layer.fillColor = [UIColor clearColor].CGColor;
              layer.fillRule = kCAFillRuleEvenOdd;    
              layer.lineCap = kCALineCapRound;   
              layer.lineJoin = kCALineJoinRound;    // 结合 CABasicAnimation 可以变成 动画绘制    // 将layer添加进图层   
              [self.view.layer addSublayer:layer];   
              [self.drawPaths addObject:path];   
              [self.drawLayers addObject:layer];   
     }    
    - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{  
              [super touchesMoved:touches withEvent:event];                      
              UIBezierPath * path = self.drawPaths.lastObject;      
              CAShapeLayer * layer = self.drawLayers.lastObject;                    
              [path addLineToPoint:[[touches anyObject] locationInView:self.view]];       
              layer.path = path.CGPath;      
    }        
    - (NSMutableArray *)drawPaths{      
       if (_drawPaths == nil) {     
           _drawPaths = [NSMutableArray array];     
       }       
       return _drawPaths;      
    }       
    - (NSMutableArray *)drawLayers{     
        if (_drawLayers == nil) {       
              _drawLayers = [NSMutableArray array];    
        }      
        return _drawLayers;   
    }
    

    </code>

    有人可能会问了,这么写,会不会有问题,为什么不用一个UIBezierPath曲线画,我是这样考虑的:
    1.一条曲线渲染速度太慢,画的越多,渲染的速度越慢.会造成延时渲染的效果.这个是我跳入的坑,刚爬出来.
    2.对于画板的需求来说,回撤的可能是非常大的.一条曲线不容易操作
    对于一条曲线来说,如果渲染慢的话,还是可以解决的,不过要调用,layer的-setNeedsDisplayInRect:方法对touch附近的区域进行渲染,这个继续研究

    有不明白的欢迎下载Demo

    相关文章

      网友评论

      • dtythicc:哇用CAShaperLayer 果然比 DrawRect 方法节省很多内存,学习了!
      • 七夜大人:用上了,多谢.

      本文标题:CAShapeLayer画板

      本文链接:https://www.haomeiwen.com/subject/dhofettx.html