CSignatureDrawView.m 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. //
  2. // CSignatureDrawView.m
  3. // ComPDFKit_Tools
  4. //
  5. // Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  8. // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  9. // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  10. // This notice may not be removed from this file.
  11. //
  12. #import "CSignatureDrawView.h"
  13. static CGPoint _points[5];
  14. static NSInteger _index;
  15. @interface CSignatureDrawView ()
  16. @property (nonatomic, strong) UIBezierPath *bezierPath;
  17. @property (nonatomic, assign) CGRect textRect;
  18. @property (nonatomic, assign) CGContextRef context;
  19. @end
  20. @implementation CSignatureDrawView
  21. #pragma mark - Initializers
  22. - (instancetype)initWithFrame:(CGRect)frame {
  23. if (self = [super initWithFrame:frame]) {
  24. self.bezierPath = [[UIBezierPath alloc] init];
  25. self.lineWidth = 1;
  26. self.backgroundColor = [UIColor clearColor];
  27. }
  28. return self;
  29. }
  30. - (void)layoutSubviews {
  31. [super layoutSubviews];
  32. [self setNeedsDisplayInRect:self.bounds];
  33. }
  34. - (void)drawRect:(CGRect)rect {
  35. [super drawRect:rect];
  36. self.context = UIGraphicsGetCurrentContext();
  37. if (CSignatureDrawText == self.selectIndex) {
  38. [self.color set];
  39. [self.bezierPath setLineWidth:self.lineWidth];
  40. [self.bezierPath setLineCapStyle:kCGLineCapRound];
  41. [self.bezierPath setLineJoinStyle:kCGLineJoinRound];
  42. [self.bezierPath stroke];
  43. } else if (CSignatureDrawImage) {
  44. if (self.image) {
  45. CGRect imageFrame = [self imageFrameInRect:rect];
  46. [self.image drawInRect:imageFrame];
  47. if (self.delegate && [self.delegate respondsToSelector:@selector(signatureDrawViewStart:)]) {
  48. [self.delegate signatureDrawViewStart:self];
  49. }
  50. }
  51. }
  52. }
  53. #pragma mark - Draw Methods
  54. - (CGRect)imageFrameInRect:(CGRect)rect {
  55. CGRect imageRect;
  56. if (self.image.size.width < rect.size.width &&
  57. self.image.size.height < rect.size.height) {
  58. imageRect.origin.x = (rect.size.width-self.image.size.width)/2.0;
  59. imageRect.origin.y = (rect.size.height-self.image.size.height)/2.0;
  60. imageRect.size = self.image.size;
  61. } else {
  62. if (self.image.size.width/self.image.size.height >
  63. rect.size.width/rect.size.height) {
  64. imageRect.size.width = rect.size.width;
  65. imageRect.size.height = rect.size.width*self.image.size.height/self.image.size.width;
  66. } else {
  67. imageRect.size.height = rect.size.height;
  68. imageRect.size.width = rect.size.height*self.image.size.width/self.image.size.height;
  69. }
  70. imageRect.origin.x = (rect.size.width-imageRect.size.width)/2.0;
  71. imageRect.origin.y = (rect.size.height-imageRect.size.height)/2.0;
  72. }
  73. return imageRect;
  74. }
  75. #pragma mark - Public Methods
  76. - (UIImage *)signatureImage {
  77. CGRect rect = CGRectZero;
  78. CGRect imageFrame = [self imageFrameInRect:self.frame];
  79. if (self.image) {
  80. if (self.bezierPath.empty) {
  81. rect = imageFrame;
  82. } else {
  83. CGRect pathFrame = self.bezierPath.bounds;
  84. rect.origin.x = MIN(CGRectGetMinX(imageFrame), CGRectGetMinX(pathFrame));
  85. rect.origin.y = MIN(CGRectGetMinY(imageFrame), CGRectGetMinY(pathFrame));
  86. rect.size.width = MAX(CGRectGetMaxX(imageFrame), CGRectGetMaxX(pathFrame))-rect.origin.x;
  87. rect.size.height = MAX(CGRectGetMaxY(imageFrame), CGRectGetMaxY(pathFrame))-rect.origin.y;
  88. }
  89. } else {
  90. if (self.bezierPath.empty) {
  91. return nil;
  92. } else {
  93. rect = self.bezierPath.bounds;
  94. }
  95. }
  96. CGSize size = CGSizeMake(rect.size.width+self.bezierPath.lineWidth,
  97. rect.size.height+self.bezierPath.lineWidth);
  98. UIGraphicsBeginImageContext(size);
  99. CGContextRef context = UIGraphicsGetCurrentContext();
  100. CGAffineTransform transform = CGAffineTransformMakeTranslation(-rect.origin.x+self.bezierPath.lineWidth/2.0, -rect.origin.y+self.bezierPath.lineWidth/2.0);
  101. CGContextConcatCTM(context, transform);
  102. if (self.image) {
  103. [self.image drawInRect:imageFrame];
  104. }
  105. if (!self.bezierPath.empty) {
  106. CGContextSetStrokeColorWithColor(context, self.color.CGColor);
  107. CGContextSetLineWidth(context, self.bezierPath.lineWidth);
  108. CGContextSetLineCap(context, self.bezierPath.lineCapStyle);
  109. CGContextSetLineJoin(context, self.bezierPath.lineJoinStyle);
  110. CGContextAddPath(context, self.bezierPath.CGPath);
  111. CGContextStrokePath(context);
  112. }
  113. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  114. UIGraphicsEndImageContext();
  115. return image;
  116. }
  117. #pragma mark - Public Methods
  118. - (void)signatureClear {
  119. self.image = nil;
  120. [self.bezierPath removeAllPoints];
  121. [self setNeedsDisplay];
  122. }
  123. #pragma mark - Action
  124. - (void)buttonItemClicked_clear:(UIButton *)button {
  125. self.image = nil;
  126. [self.bezierPath removeAllPoints];
  127. [self setNeedsDisplay];
  128. }
  129. #pragma mark - Touch Methods
  130. - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  131. [super touchesBegan:touches withEvent:event];
  132. CGPoint point = [[touches anyObject] locationInView:self];
  133. _index = 0;
  134. _points[0] = point;
  135. if (self.delegate && [self.delegate respondsToSelector:@selector(signatureDrawViewStart:)]) {
  136. [self.delegate signatureDrawViewStart:self];
  137. }
  138. }
  139. - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  140. [super touchesMoved:touches withEvent:event];
  141. CGPoint point = [[touches anyObject] locationInView:self];
  142. _index++;
  143. _points[_index] = point;
  144. if (_index == 4) {
  145. _points[3] = CGPointMake((_points[2].x + _points[4].x)/2.0,
  146. (_points[2].y + _points[4].y)/2.0);
  147. [self.bezierPath moveToPoint:_points[0]];
  148. [self.bezierPath addCurveToPoint:_points[3]
  149. controlPoint1:_points[1]
  150. controlPoint2:_points[2]];
  151. _points[0] = _points[3];
  152. _points[1] = _points[4];
  153. _index = 1;
  154. [self setNeedsDisplay];
  155. }
  156. }
  157. - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  158. [super touchesEnded:touches withEvent:event];
  159. if (_index < 4) {
  160. for (int i=0; i<_index; i++) {
  161. [self.bezierPath moveToPoint:_points[i]];
  162. }
  163. [self setNeedsDisplay];
  164. }
  165. }
  166. @end