iOS手寫(xiě)簽名

前段時(shí)間有個(gè)朋友讓幫忙寫(xiě)一個(gè)手寫(xiě)簽名的功能,自己利用業(yè)余時(shí)間做了一下也算復(fù)習(xí)了下基礎(chǔ)知識(shí),現(xiàn)在整理出來(lái)寫(xiě)到簡(jiǎn)書(shū)上;
關(guān)于手寫(xiě)簽名,我先是找了下別人的博客,有一個(gè)寫(xiě)的就很好,我把地址貼出來(lái),大家可以參考一下
IOS:手寫(xiě)簽名的實(shí)現(xiàn)實(shí)現(xiàn)了手勢(shì)繪制字體,添加文字水印,圖片剪切、圖片壓縮
主要是我的需求比較簡(jiǎn)單,看著人家寫(xiě)的這么詳細(xì) 不忍心抄寫(xiě),所以決定自己寫(xiě),先上效果圖:

手寫(xiě)簽名效果圖.gif

我的思路是,在控制器中添加一個(gè)自定義的簽名的View:signatureView,再設(shè)置一個(gè)重簽的按鈕用來(lái)清除重寫(xiě),一個(gè)確認(rèn)的按鈕,將簽名保存下來(lái);


簽名頁(yè)面.png

頁(yè)面比較簡(jiǎn)單,為了少寫(xiě)一些成員變量,我把布局也寫(xiě)在了ViewDidLoad中

1、頁(yè)面布局的代碼如下:

1.1 頁(yè)面布局

    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:@"確認(rèn)" 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 兩個(gè)按鈕的方法:

// 清除按鈕方法
-(void)clear:(UIButton *)btn{
    
    [self.signatureView clearScreen];
 
}
// 確定按鈕方法
-(void)confirmBtnClick:(UIButton *)btn {
        NSLog(@"確定保存");
    
    // 開(kāi)啟位圖上下文
    UIGraphicsBeginImageContextWithOptions(_signatureView.bounds.size, NO, 0);
    
    // 獲取當(dāng)前位圖上下文
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    
    // 截屏內(nèi)容到上下文
    [_signatureView.layer renderInContext:ctx];
    
    // 獲取圖片
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    
    // 關(guān)閉上下文
    UIGraphicsEndImageContext();
    // 這里拿到簽名后的圖片,可以保存到相冊(cè)
    // 保存到手機(jī)相冊(cè)
    UIImageWriteToSavedPhotosAlbum(img, self, @selector(image:didFinishSavingWithError:contextInfo:), nil);
// 我這里是通過(guò)block傳值給上一個(gè)頁(yè)面
    if (self.signBlock) {
        self.signBlock(img);
    }
    [self.navigationController popViewControllerAnimated:YES];
    
}

如果保存到相冊(cè),回調(diào)方法:

// 保存相冊(cè)成功之后的回調(diào)方法
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
    if (error) {
        NSLog(@"保存成功");

       // [MBProgressHUD showError:@"保存失敗"];
    }else{
        // 保存成功
NSLog(@"保存失敗");
        //[MBProgressHUD showSuccess:@"保存成功"];
        
    }
}```

###2. signatureView
首先重寫(xiě)initWithFrame: 設(shè)置默認(rèn)的lineWidth 和color,我們把lineWidth和color設(shè)置成屬性,暴露到.h頭文件中,方便控制器中修改;

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

我們?cè)趖ouchesBegan: 和touchesMoved: 中創(chuàng)建和繪制UIBezierPath 路徑 
  • (CGPoint)pointWithTouches:(NSSet *)touches
    {
    // 獲取touch對(duì)象
    UITouch *touch = [touches anyObject];
    // 獲取當(dāng)前觸摸點(diǎn)
    return [touch locationInView:self];
    }
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    CGPoint curP = [self pointWithTouches:touches];
    // 創(chuàng)建路徑
    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 的子類(lèi),為了給UIBezierPath拓展color屬性 
  • (instancetype)pathWitchColor:(UIColor *)color lineWidth:(CGFloat)lineWidth
    {
    DrawPath *path = [[self alloc] init];
    path.color = color;
    path.lineWidth = lineWidth;

    return path;
    }

繪制完成后調(diào)用 [self setNeedsDisplay] 系統(tǒng)會(huì)調(diào)用 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;

}

如此我們就用繪圖的方法 簡(jiǎn)單實(shí)現(xiàn)了手寫(xiě)簽名功能;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容