美文网首页iOS
iOS手写签名

iOS手写签名

作者: MyNameIsMrLeon | 来源:发表于2017-06-20 11:50 被阅读104次

    前段时间有个朋友让帮忙写一个手写签名的功能,自己利用业余时间做了一下也算复习了下基础知识,现在整理出来写到简书上;
    关于手写签名,我先是找了下别人的博客,有一个写的就很好,我把地址贴出来,大家可以参考一下
    IOS:手写签名的实现实现了手势绘制字体,添加文字水印,图片剪切、图片压缩
    主要是我的需求比较简单,看着人家写的这么详细 不忍心抄写,所以决定自己写,先上效果图:

    手写签名效果图.gif

    我的思路是,在控制器中添加一个自定义的签名的View:signatureView,再设置一个重签的按钮用来清除重写,一个确认的按钮,将签名保存下来;


    签名页面.png

    页面比较简单,为了少写一些成员变量,我把布局也写在了ViewDidLoad中

    1、页面布局的代码如下:

    1.1 页面布局

        self.view.backgroundColor = [UIColor grayColor];
        self.signatureView = [[signatureView alloc]initWithFrame:CGRectMake(10, 70, self.view.width - 20, (self.view.width - 20)*0.4)];
        self.signatureView.backgroundColor = [UIColor whiteColor];
        self.signatureView.color = [UIColor blackColor];
        self.signatureView.lineWidth = 2;
        
        [self.view addSubview:self.signatureView];
        
        UIButton *reSignBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [reSignBtn setTitle:@"重签" forState:UIControlStateNormal];
        [reSignBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        
        [reSignBtn setFrame:CGRectMake(20, CGRectGetMaxY(self.signatureView.frame)+10, (self.view.width - 20*3)*0.5, 40)];
        
        reSignBtn.layer.cornerRadius = 5.0;
        reSignBtn.clipsToBounds = YES;
        reSignBtn.layer.borderWidth = 1.0;
        
        reSignBtn.titleLabel.font = [UIFont systemFontOfSize:17];
        
        [reSignBtn addTarget:self action:@selector(clear:) forControlEvents:UIControlEventTouchUpInside];
        
        [self.view addSubview:reSignBtn];
        
        
        UIButton *confirmBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        [confirmBtn setTitle:@"确认" forState:UIControlStateNormal];
        [confirmBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        confirmBtn.titleLabel.font = [UIFont systemFontOfSize:17.0];
        
        confirmBtn.backgroundColor = [UIColor greenColor];
        
        confirmBtn.frame = CGRectMake(CGRectGetMaxX(reSignBtn.frame)+20, reSignBtn.y, reSignBtn.width, reSignBtn.height);
        confirmBtn.layer.cornerRadius = 5.0;
        confirmBtn.clipsToBounds = YES;
        [confirmBtn addTarget:self action:@selector(confirmBtnClick:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:confirmBtn];
    

    1.2 两个按钮的方法:

    // 清除按钮方法
    -(void)clear:(UIButton *)btn{
        
        [self.signatureView clearScreen];
     
    }
    // 确定按钮方法
    -(void)confirmBtnClick:(UIButton *)btn {
            NSLog(@"确定保存");
        
        // 开启位图上下文
        UIGraphicsBeginImageContextWithOptions(_signatureView.bounds.size, NO, 0);
        
        // 获取当前位图上下文
        CGContextRef ctx = UIGraphicsGetCurrentContext();
        
        // 截屏内容到上下文
        [_signatureView.layer renderInContext:ctx];
        
        // 获取图片
        UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
        
        // 关闭上下文
        UIGraphicsEndImageContext();
        // 这里拿到签名后的图片,可以保存到相册
        // 保存到手机相册
        UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
    // 我这里是通过block传值给上一个页面
        if (self.signBlock) {
            self.signBlock(img);
        }
        [self.navigationController popViewControllerAnimated:YES];
        
    }
    

    如果保存到相册,回调方法:

    // 保存相册成功之后的回调方法
    - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
    {
        if (error) {
            NSLog(@"保存成功");
    
           // [MBProgressHUD showError:@"保存失败"];
        }else{
            // 保存成功
    NSLog(@"保存失败");
            //[MBProgressHUD showSuccess:@"保存成功"];
            
        }
    }```
    
    ###2. signatureView
    首先重写initWithFrame: 设置默认的lineWidth 和color,我们把lineWidth和color设置成属性,暴露到.h头文件中,方便控制器中修改;
    

    -(instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]){
    _lineWidth = 1;
    _color = [UIColor blackColor];
    }
    return self;
    }

    我们在touchesBegan: 和touchesMoved: 中创建和绘制UIBezierPath 路径 
    
    • (CGPoint)pointWithTouches:(NSSet *)touches
      {
      // 获取touch对象
      UITouch *touch = [touches anyObject];
      // 获取当前触摸点
      return [touch locationInView:self];
      }
      -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

      CGPoint curP = [self pointWithTouches:touches];
      // 创建路径
      DrawPath *path = [DrawPath pathWitchColor:_color lineWidth:_lineWidth];
      [path moveToPoint:curP];
      _path = path;

      [self.paths addObject:path];
      }
      -(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
      CGPoint curP = [self pointWithTouches:touches];
      [_path addLineToPoint:curP];
      [self setNeedsDisplay];

    }

    上面的DrawPath 是继承自UIBezierPath 的子类,为了给UIBezierPath拓展color属性 
    
    • (instancetype)pathWitchColor:(UIColor *)color lineWidth:(CGFloat)lineWidth
      {
      DrawPath *path = [[self alloc] init];
      path.color = color;
      path.lineWidth = lineWidth;

      return path;
      }

    绘制完成后调用 [self setNeedsDisplay] 系统会调用 drawRect:方法完成绘制
    

    -(void)drawRect:(CGRect)rect{
    if (self.paths.count == 0) {
    return;
    }
    for (DrawPath *path in self.paths) {
    [path.color set];
    [path stroke];
    }
    }

    另外的清屏操作和懒加载代码如下:
    

    // 清屏

    • (void)clearScreen
      {
      // 清空所有的路径
      [self.paths removeAllObjects];

      [self setNeedsDisplay];
      }
      // 懒加载
      -(NSMutableArray *)paths{
      if (!_path) {
      _paths = [NSMutableArray array];

      }
      return _paths;

    }

    如此我们就用绘图的方法 简单实现了手写签名功能;

    相关文章

      网友评论

      本文标题:iOS手写签名

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