KKEmoticonView.m 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //
  2. // KKEmoticonView.m
  3. // WWImageEdit
  4. //
  5. // Created by 邬维 on 2017/1/12.
  6. // Copyright © 2017年 kook. All rights reserved.
  7. //
  8. #import "KKEmoticonView.h"
  9. #import "KKEmoticonTool.h"
  10. #import "KKScaleButton.h"
  11. static const NSUInteger kDeleteBtnSize = 32;
  12. @implementation KKEmoticonView{
  13. UIImageView *_imageView; //表情图片
  14. UIButton *_deleteButton; //删除按钮
  15. KKScaleButton *_scaleBtn;
  16. CGFloat _scale; //当前缩放比例
  17. CGFloat _arg; //当前旋转比例
  18. CGPoint _initialPoint; //表情的中心点
  19. CGFloat _initialScale; //修改前的缩放比例
  20. CGFloat _initialArg; //修改前旋转比例
  21. }
  22. + (void)setActiveEmoticonView:(KKEmoticonView*)view
  23. {
  24. static KKEmoticonView *activeView = nil;
  25. if(view != activeView){
  26. [activeView setAvtive:NO]; //隐藏上一个表情的线和按钮
  27. activeView = view;
  28. //显示当前表情的线和按钮
  29. [activeView setAvtive:YES];
  30. //显示在最上层
  31. [activeView.superview bringSubviewToFront:activeView];
  32. }
  33. }
  34. - (instancetype)initWithImage:(UIImage *)image tool:(KKEmoticonTool *)tool{
  35. self = [super initWithFrame:CGRectMake(0, 0, image.size.width+kDeleteBtnSize, image.size.height+kDeleteBtnSize)];
  36. if (self) {
  37. _imageView = [[UIImageView alloc] initWithImage:image];
  38. _imageView.layer.borderColor = [[UIColor blackColor] CGColor];
  39. _imageView.layer.cornerRadius = 3;
  40. _imageView.center = self.center;
  41. [self addSubview:_imageView];
  42. _deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
  43. [_deleteButton setImage:[UIImage imageNamed:@"btn_delete"] forState:UIControlStateNormal];
  44. _deleteButton.frame = CGRectMake(0, 0, 32, 32);
  45. _deleteButton.center = _imageView.frame.origin;
  46. [_deleteButton addTarget:self action:@selector(clickDeleteBtn:) forControlEvents:UIControlEventTouchUpInside];
  47. [self addSubview:_deleteButton];
  48. _scaleBtn = [[KKScaleButton alloc] initWithFrame:CGRectMake(0, 0, kDeleteBtnSize, kDeleteBtnSize)];
  49. _scaleBtn.center = CGPointMake(_imageView.width + _imageView.frame.origin.x, _imageView.height + _imageView.frame.origin.y);
  50. _scaleBtn.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
  51. [self addSubview:_scaleBtn];
  52. _scale = 1;
  53. _arg = 0;
  54. [self initGestures];
  55. }
  56. return self;
  57. }
  58. - (void)initGestures
  59. {
  60. _imageView.userInteractionEnabled = YES;
  61. [_imageView addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(imageDidPan:)]];
  62. [_scaleBtn addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(scaleBtnDidPan:)]];
  63. }
  64. //删除
  65. - (void)clickDeleteBtn:(id)sender
  66. {
  67. KKEmoticonView *nextTarget = nil;
  68. const NSInteger index = [self.superview.subviews indexOfObject:self];
  69. for(NSInteger i=index+1; i<self.superview.subviews.count; ++i){
  70. UIView *view = [self.superview.subviews objectAtIndex:i];
  71. if([view isKindOfClass:[KKEmoticonView class]]){
  72. nextTarget = (KKEmoticonView *)view;
  73. break;
  74. }
  75. }
  76. if(nextTarget==nil){
  77. for(NSInteger i=index-1; i>=0; --i){
  78. UIView *view = [self.superview.subviews objectAtIndex:i];
  79. if([view isKindOfClass:[KKEmoticonView class]]){
  80. nextTarget = (KKEmoticonView*)view;
  81. break;
  82. }
  83. }
  84. }
  85. [[self class] setActiveEmoticonView:nextTarget];
  86. [self removeFromSuperview];
  87. }
  88. - (void)setAvtive:(BOOL)active
  89. {
  90. _deleteButton.hidden = !active;
  91. _scaleBtn.hidden = !active;
  92. _imageView.layer.borderWidth = (active) ? 1/_scale : 0;
  93. }
  94. - (void)setScale:(CGFloat)scale
  95. {
  96. _scale = scale;
  97. self.transform = CGAffineTransformIdentity;
  98. _imageView.transform = CGAffineTransformMakeScale(_scale, _scale); //缩放
  99. CGRect rct = self.frame;
  100. rct.origin.x += (rct.size.width - (_imageView.width + 32)) / 2;
  101. rct.origin.y += (rct.size.height - (_imageView.height + 32)) / 2;
  102. rct.size.width = _imageView.width + 32;
  103. rct.size.height = _imageView.height + 32;
  104. self.frame = rct;
  105. _imageView.center = CGPointMake(rct.size.width/2, rct.size.height/2);
  106. self.transform = CGAffineTransformMakeRotation(_arg); //旋转
  107. _imageView.layer.borderWidth = 1/_scale;
  108. _imageView.layer.cornerRadius = 3/_scale;
  109. }
  110. //拖动
  111. - (void)imageDidPan:(UIPanGestureRecognizer*)sender
  112. {
  113. [[self class] setActiveEmoticonView:self];
  114. CGPoint p = [sender translationInView:self.superview];
  115. if(sender.state == UIGestureRecognizerStateBegan){
  116. _initialPoint = self.center;
  117. }
  118. self.center = CGPointMake(_initialPoint.x + p.x, _initialPoint.y + p.y);
  119. }
  120. //缩放
  121. - (void)scaleBtnDidPan:(UIPanGestureRecognizer*)sender
  122. {
  123. CGPoint p = [sender translationInView:self.superview];
  124. static CGFloat tmpR = 1; //临时缩放值
  125. static CGFloat tmpA = 0; //临时旋转值
  126. if(sender.state == UIGestureRecognizerStateBegan){
  127. //表情view中的缩放按钮相对与表情view父视图中的位置
  128. _initialPoint = [self.superview convertPoint:_scaleBtn.center fromView:_scaleBtn.superview];
  129. CGPoint p = CGPointMake(_initialPoint.x - self.center.x, _initialPoint.y - self.center.y);
  130. //缩放按钮中点与表情view中点的直线距离
  131. tmpR = sqrt(p.x*p.x + p.y*p.y); //开根号
  132. //缩放按钮中点与表情view中点连线的斜率角度
  133. tmpA = atan2(p.y, p.x);//反正切函数
  134. _initialArg = _arg;
  135. _initialScale = _scale;
  136. }
  137. p = CGPointMake(_initialPoint.x + p.x - self.center.x, _initialPoint.y + p.y - self.center.y);
  138. CGFloat R = sqrt(p.x*p.x + p.y*p.y); //拖动后的距离
  139. CGFloat arg = atan2(p.y, p.x); // 拖动后的旋转角度
  140. //旋转角度
  141. _arg = _initialArg + arg - tmpA; //原始角度+拖动后的角度 - 拖动前的角度
  142. //放大缩小的值
  143. [self setScale:MAX(_initialScale * R / tmpR, 0.2)];
  144. }
  145. @end