PDFSignatureDrawView.m 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. //
  2. // PDFSignatureDrawView.m
  3. // PDFReader
  4. //
  5. // Copyright © 2014-2022 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // The PDF Reader Sample applications are licensed with a modified BSD license.
  8. // Please see License for details. This notice may not be removed from this file.
  9. //
  10. #import "PDFSignatureDrawView.h"
  11. static CGPoint _points[5];
  12. static NSInteger _index;
  13. @interface PDFSignatureDrawView ()
  14. @property (nonatomic,retain) UIBezierPath *bezierPath;
  15. @end
  16. @implementation PDFSignatureDrawView
  17. #pragma mark - Init Methods
  18. - (instancetype)initWithFrame:(CGRect)frame {
  19. if (self = [super initWithFrame:frame]) {
  20. _bezierPath = [[UIBezierPath alloc] init];
  21. _color = [[UIColor blackColor] retain];
  22. _lineWidth = 5;
  23. }
  24. return self;
  25. }
  26. - (instancetype)initWithCoder:(NSCoder *)aDecoder {
  27. if (self = [super initWithCoder:aDecoder]) {
  28. _bezierPath = [[UIBezierPath alloc] init];
  29. _color = [[UIColor blackColor] retain];
  30. _lineWidth = 5;
  31. }
  32. return self;
  33. }
  34. - (void)dealloc {
  35. [_image release];
  36. [_color release];
  37. [_bezierPath release];
  38. [super dealloc];
  39. }
  40. #pragma mark - Draw Methods
  41. - (void)layoutSubviews {
  42. [super layoutSubviews];
  43. [self setNeedsDisplay];
  44. }
  45. - (void)drawRect:(CGRect)rect {
  46. [super drawRect:rect];
  47. if (self.image) {
  48. CGRect imageFrame = [self imageFrameInRect:rect];
  49. [self.image drawInRect:imageFrame];
  50. }
  51. [self.color set];
  52. [self.bezierPath setLineWidth:self.lineWidth];
  53. [self.bezierPath setLineCapStyle:kCGLineCapRound];
  54. [self.bezierPath setLineJoinStyle:kCGLineJoinRound];
  55. [self.bezierPath stroke];
  56. }
  57. - (CGRect)imageFrameInRect:(CGRect)rect {
  58. CGRect imageRect;
  59. if (self.image.size.width < rect.size.width &&
  60. self.image.size.height < rect.size.height) {
  61. imageRect.origin.x = (rect.size.width-self.image.size.width)/2.0;
  62. imageRect.origin.y = (rect.size.height-self.image.size.height)/2.0;
  63. imageRect.size = self.image.size;
  64. } else {
  65. if (self.image.size.width/self.image.size.height >
  66. rect.size.width/rect.size.height) {
  67. imageRect.size.width = rect.size.width;
  68. imageRect.size.height = rect.size.width*self.image.size.height/self.image.size.width;
  69. } else {
  70. imageRect.size.height = rect.size.height;
  71. imageRect.size.width = rect.size.height*self.image.size.width/self.image.size.height;
  72. }
  73. imageRect.origin.x = (rect.size.width-imageRect.size.width)/2.0;
  74. imageRect.origin.y = (rect.size.height-imageRect.size.height)/2.0;
  75. }
  76. return imageRect;
  77. }
  78. #pragma mark - Public Mehtods
  79. - (UIImage *)signatureImage {
  80. CGRect rect = CGRectZero;
  81. CGRect imageFrame = [self imageFrameInRect:self.frame];
  82. if (self.image) {
  83. if (self.bezierPath.empty) {
  84. rect = imageFrame;
  85. } else {
  86. CGRect pathFrame = self.bezierPath.bounds;
  87. rect.origin.x = MIN(CGRectGetMinX(imageFrame), CGRectGetMinX(pathFrame));
  88. rect.origin.y = MIN(CGRectGetMinY(imageFrame), CGRectGetMinY(pathFrame));
  89. rect.size.width = MAX(CGRectGetMaxX(imageFrame), CGRectGetMaxX(pathFrame))-rect.origin.x;
  90. rect.size.height = MAX(CGRectGetMaxY(imageFrame), CGRectGetMaxY(pathFrame))-rect.origin.y;
  91. }
  92. } else {
  93. if (self.bezierPath.empty) {
  94. return nil;
  95. } else {
  96. rect = self.bezierPath.bounds;
  97. }
  98. }
  99. CGSize size = CGSizeMake(rect.size.width+self.bezierPath.lineWidth,
  100. rect.size.height+self.bezierPath.lineWidth);
  101. UIGraphicsBeginImageContext(size);
  102. CGContextRef context = UIGraphicsGetCurrentContext();
  103. CGAffineTransform transform = CGAffineTransformMakeTranslation(-rect.origin.x+self.bezierPath.lineWidth/2.0, -rect.origin.y+self.bezierPath.lineWidth/2.0);
  104. CGContextConcatCTM(context, transform);
  105. if (self.image) {
  106. [self.image drawInRect:imageFrame];
  107. }
  108. if (!self.bezierPath.empty) {
  109. CGContextSetStrokeColorWithColor(context, self.color.CGColor);
  110. CGContextSetLineWidth(context, self.bezierPath.lineWidth);
  111. CGContextSetLineCap(context, self.bezierPath.lineCapStyle);
  112. CGContextSetLineJoin(context, self.bezierPath.lineJoinStyle);
  113. CGContextAddPath(context, self.bezierPath.CGPath);
  114. CGContextStrokePath(context);
  115. }
  116. UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  117. UIGraphicsEndImageContext();
  118. return image;
  119. }
  120. - (void)clear {
  121. self.image = nil;
  122. [self.bezierPath removeAllPoints];
  123. [self setNeedsDisplay];
  124. }
  125. - (void)setColor:(UIColor *)color {
  126. if (_color != color) {
  127. [_color release];
  128. _color = [color retain];
  129. }
  130. [self setNeedsDisplay];
  131. }
  132. - (void)setLineWidth:(CGFloat)lineWidth {
  133. _lineWidth = lineWidth;
  134. [self setNeedsDisplay];
  135. }
  136. - (void)setImage:(UIImage *)image {
  137. if (_image != image) {
  138. [_image release];
  139. _image = [image retain];
  140. }
  141. [self setNeedsDisplay];
  142. }
  143. #pragma mark - Touch Methods
  144. - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  145. [super touchesBegan:touches withEvent:event];
  146. CGPoint point = [[touches anyObject] locationInView:self];
  147. _index = 0;
  148. _points[0] = point;
  149. }
  150. - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  151. [super touchesMoved:touches withEvent:event];
  152. CGPoint point = [[touches anyObject] locationInView:self];
  153. _index++;
  154. _points[_index] = point;
  155. if (_index == 4) {
  156. _points[3] = CGPointMake((_points[2].x + _points[4].x)/2.0,
  157. (_points[2].y + _points[4].y)/2.0);
  158. [self.bezierPath moveToPoint:_points[0]];
  159. [self.bezierPath addCurveToPoint:_points[3]
  160. controlPoint1:_points[1]
  161. controlPoint2:_points[2]];
  162. _points[0] = _points[3];
  163. _points[1] = _points[4];
  164. _index = 1;
  165. [self setNeedsDisplay];
  166. }
  167. }
  168. - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  169. [super touchesEnded:touches withEvent:event];
  170. if (_index < 4) {
  171. for (int i=0; i<_index; i++) {
  172. [self.bezierPath moveToPoint:_points[i]];
  173. }
  174. [self setNeedsDisplay];
  175. }
  176. }
  177. @end