1. UKAutographView
UKAutographView
控件用来实现自定义签名功能,UKAutographView
实现UIView
@interface UKAutographView()
// path记录当前绘制路径
@property(nonatomic, strong) UIBezierPath *path;
// paths记录所有绘制路径
@property(nonatomic, strong) NSMutableArray<UIBezierPath *> *paths;
// points记录所有绘制路径上的点
@property(nonatomic, strong) NSMutableArray<NSValue *> *points;
// 宽高比,默认1.25
@property(nonatomic, assign) CGFloat imageRatio;
@end
UKAutographView
有两个功能,
- 记录所有的绘制点,在
touchesBegan
初始化当前绘制路径,在touchesMoved
里面往当前绘制路径里面添加绘制点。 - 在
drawRect:(CGRect)rect
方法里面绘制签名。
@implementation UKAutographView
- (instancetype)init {
self = [super init];
if (self) {
self.paths = [[NSMutableArray alloc] init];
self.points = [[NSMutableArray alloc] init];
self.imageRatio = 1.25;
self.backgroundColor = [UIColor clearColor];
}
return self;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 1.获取触摸对象
UITouch *touch = touches.anyObject;
// 2.获取触摸点
CGPoint locP = [touch locationInView:touch.view];
//3.创建绘图路径
self.path = [[UIBezierPath alloc] init];
self.path.lineWidth = 6;
self.path.lineCapStyle = kCGLineCapRound;
self.path.lineJoinStyle = kCGLineJoinRound;
// 4.添加子路径
[self.path moveToPoint:locP];
[self.points addObject:[NSValue valueWithCGPoint:locP]];
// 5.把path添加到数组中
[self.paths addObject:self.path];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
UITouch *touch = touches.anyObject;
CGPoint locP = [touch locationInView:touch.view];
[self.path addLineToPoint:locP];
[self.points addObject:[NSValue valueWithCGPoint:locP]];
[self setNeedsDisplay];
if (self.delegate) {
[self.delegate autographViewDidBegin:self];
}
}
- (void)drawRect:(CGRect)rect {
//设置颜色
[[UIColor blackColor] set];
for (UIBezierPath *path in self.paths) {
[path stroke];
}
}
@end
UKAutographView
其他方法
// 设置生成签名的宽高比
- (void)setImageRatio:(CGFloat)ratio {
_imageRatio = ratio;
}
// 清空已有签名
- (void)clear {
[self.paths removeAllObjects];
[self.points removeAllObjects];
[self setNeedsDisplay];
}
// 获取当前签名
- (UIImage *)save {
CGPoint point = self.points.firstObject.CGPointValue;
CGFloat left = point.x;
CGFloat right = point.x;
CGFloat top = point.y;
CGFloat bottom = point.y;
for (NSValue *pointValue in self.points) {
CGPoint point = pointValue.CGPointValue;
if (point.x < left) {
left = point.x;
} else if (point.x > right) {
right = point.x;
}
if (point.y < top) {
top = point.y;
} else if (point.y > bottom) {
bottom = point.y;
}
}
CGFloat height = bottom - top;
CGFloat width = right - left;
if (width / height > self.imageRatio) {
CGFloat newHeight = width / self.imageRatio;
top -= (newHeight - height) / 2;
bottom = top + newHeight;
} else {
CGFloat newWidth = height * self.imageRatio;
left -= (newWidth - width) / 2;
right = left + newWidth;
}
CGRect imageRect = CGRectMake(left - 1, top - 1, right - left + 2, bottom - top + 2);
// 开启上下文 参数1:CGSize size 尺寸, 参数2:BOOL opaque 透明度, 参数3:CGFloat scale 比例
UIGraphicsBeginImageContextWithOptions(imageRect.size, NO, [UIScreen mainScreen].scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGContextTranslateCTM(context, -imageRect.origin.x, -imageRect.origin.y);
// 获取图像
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
CGContextRestoreGState(context);
UIImage *saveImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return saveImage;
}
2. 签名界面
为了保持签名的范围,我们会让签名界面保持横屏状态
- (UIView *)contentView {
if (!_contentView) {
CGFloat width = kScreenHeight - kStatusBarHeight - 50 - kBottomSafeHeight;
CGFloat height = kScreenWidth;
CGPoint center = CGPointMake(height/2, kStatusBarHeight + 50 + width / 2);
_contentView = [[UIView alloc] initWithFrame:CGRectMake(center.x - width/2, center.y - height/2, width, height)];
[_contentView setTransform:CGAffineTransformMakeRotation(M_PI_2)];
}
return _contentView;
}
效果如下
绘制过程中主要有三个事件,
// 重签按钮,清空签名并显示提示栏,提交按钮置灰
- (void)reSignClick:(UIButton *)sender {
[self.autographView clear];
self.confirmButton.enabled = NO;
self.tipsLabel.hidden = NO;
self.showImageView.hidden = YES;
}
// 提交按钮,在左上角显示手势签名
- (void)confirmClick:(UIButton *)sender {
UIImage *autographImage = [self.autographView save];
self.showImageView.image = autographImage;
self.showImageView.hidden = NO;
}
#pragma mark - UKAutographViewDelegate -
// 开始绘制,隐藏提示栏,可以提交签名
- (void)autographViewDidBegin:(UKAutographView *)autographView {
self.confirmButton.enabled = YES;
self.tipsLabel.hidden = YES;
self.showImageView.hidden = YES;
}
效果如下