TCBGMCutView.m 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. //
  2. // TCBGMCutView.m
  3. // TXXiaoShiPinDemo
  4. //
  5. // Created by linkzhzhu on 2017/12/14.
  6. // Copyright © 2017年 tencent. All rights reserved.
  7. //
  8. #import "TCBGMCutView.h"
  9. @implementation TCBGMCutViewConfig
  10. - (id)init
  11. {
  12. if (self = [super init]) {
  13. _pinWidth = PIN_WIDTH;
  14. _thumbHeight = THUMB_HEIGHT;
  15. _borderHeight = BORDER_HEIGHT;
  16. _leftPinImage = [UIImage imageNamed:@"left"];
  17. _centerPinImage = [UIImage imageNamed:@"center"];
  18. _rightPigImage = [UIImage imageNamed:@"right"];
  19. }
  20. return self;
  21. }
  22. @end
  23. @interface TCBGMCutView()
  24. @end
  25. @implementation TCBGMCutView {
  26. CGFloat _imageWidth;
  27. TCBGMCutViewConfig* _appearanceConfig;
  28. float sliderWidth;
  29. int dragIdx;//0 non 1 left 2 right
  30. }
  31. - (instancetype)initWithImageList:(NSArray *)images
  32. {
  33. _imageList = images;
  34. _appearanceConfig = [TCBGMCutViewConfig new];
  35. CGRect frame = {.origin = CGPointZero, .size = [self intrinsicContentSize]};
  36. self = [super initWithFrame:frame];
  37. [self iniSubViews];
  38. return self;
  39. }
  40. - (instancetype)initWithImageList:(NSArray *)images config:(TCBGMCutViewConfig *)config
  41. {
  42. _imageList = images;
  43. _appearanceConfig = config;
  44. self = [super initWithFrame:_appearanceConfig.frame];
  45. [self iniSubViews];
  46. return self;
  47. }
  48. - (void)iniSubViews
  49. {
  50. self.userInteractionEnabled = YES;
  51. TCPanGestureRecognizer *panGes = [[TCPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:) inview:self];
  52. [self addGestureRecognizer:panGes];
  53. CGRect frame = self.bounds;
  54. NSMutableArray *tmpList = [NSMutableArray new];
  55. for (int i = 0; i < _imageList.count; i++) {
  56. CGRect imgFrame = CGRectMake(_appearanceConfig.pinWidth + i*[self imageWidth],
  57. _appearanceConfig.borderHeight,
  58. _appearanceConfig.frame.size.width - 2 * _appearanceConfig.pinWidth,
  59. _appearanceConfig.thumbHeight);
  60. sliderWidth = _appearanceConfig.frame.size.width - 2 * _appearanceConfig.pinWidth;
  61. UIImageView *imgView = [[UIImageView alloc] initWithFrame:imgFrame];
  62. imgView.image = _imageList[i];
  63. imgView.contentMode = (_imageList.count > 1 ? UIViewContentModeScaleToFill : UIViewContentModeScaleAspectFit);
  64. imgView.contentMode = UIViewContentModeScaleToFill;
  65. [self addSubview:imgView];
  66. [tmpList addObject:imgView];
  67. }
  68. _imageViewList = tmpList;
  69. if (_appearanceConfig.leftCorverImage) {
  70. self.leftCover = [[UIImageView alloc] initWithImage:_appearanceConfig.leftCorverImage];
  71. self.leftCover.contentMode = UIViewContentModeCenter;
  72. self.leftCover.clipsToBounds = YES;
  73. }
  74. else {
  75. self.leftCover = [[UIImageView alloc] initWithFrame:CGRectZero];
  76. self.leftCover.backgroundColor = [UIColor blackColor];
  77. self.leftCover.alpha = 0.5;
  78. };
  79. [self addSubview:self.leftCover];
  80. if (_appearanceConfig.rightCoverImage) {
  81. self.rightCover = [[UIImageView alloc] initWithImage:_appearanceConfig.rightCoverImage];
  82. self.rightCover.contentMode = UIViewContentModeCenter;
  83. self.rightCover.clipsToBounds = YES;
  84. }
  85. else {
  86. self.rightCover = [[UIImageView alloc] initWithFrame:CGRectZero];
  87. self.rightCover.backgroundColor = [UIColor blackColor];
  88. self.rightCover.alpha = 0.5;
  89. }
  90. [self addSubview:self.rightCover];
  91. self.leftPin = ({
  92. UIImageView *imageView = [[UIImageView alloc] initWithImage:_appearanceConfig.leftPinImage];
  93. imageView.contentMode = UIViewContentModeScaleToFill;
  94. imageView.width = _appearanceConfig.pinWidth;
  95. [self addSubview:imageView];
  96. imageView;
  97. });
  98. self.rightPin = ({
  99. UIImageView *imageView = [[UIImageView alloc] initWithImage:_appearanceConfig.rightPigImage];
  100. imageView.contentMode = UIViewContentModeScaleToFill;
  101. imageView.width = _appearanceConfig.pinWidth;
  102. [self addSubview:imageView];
  103. imageView;
  104. });
  105. self.topBorder = ({
  106. UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
  107. [self addSubview:view];
  108. view.backgroundColor = [UIColor colorWithRed:0.14 green:0.80 blue:0.67 alpha:1];
  109. view;
  110. });
  111. self.bottomBorder = ({
  112. UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
  113. [self addSubview:view];
  114. view.backgroundColor = [UIColor colorWithRed:0.14 green:0.80 blue:0.67 alpha:1];
  115. view;
  116. });
  117. _leftPinCenterX = _appearanceConfig.pinWidth / 2;
  118. _rightPinCenterX = frame.size.width- _appearanceConfig.pinWidth / 2;
  119. }
  120. - (CGSize)intrinsicContentSize {
  121. return CGSizeMake(_appearanceConfig.frame.size.width, _appearanceConfig.thumbHeight + 2 * _appearanceConfig.borderHeight);
  122. }
  123. - (void)layoutSubviews {
  124. [super layoutSubviews];
  125. self.leftPin.center = CGPointMake(self.leftPinCenterX, self.height / 2);
  126. self.rightPin.center = CGPointMake(self.rightPinCenterX, self.height / 2);
  127. self.topBorder.height = _appearanceConfig.borderHeight;
  128. self.topBorder.width = self.rightPinCenterX - self.leftPinCenterX;
  129. self.topBorder.y = 0;
  130. self.topBorder.x = self.leftPinCenterX;
  131. self.bottomBorder.height = _appearanceConfig.borderHeight;
  132. self.bottomBorder.width = self.rightPinCenterX - self.leftPinCenterX;
  133. self.bottomBorder.y = self.leftPin.bottom-_appearanceConfig.borderHeight;
  134. self.bottomBorder.x = self.leftPinCenterX;
  135. self.leftCover.height = _appearanceConfig.thumbHeight;
  136. self.leftCover.width = self.leftPinCenterX - _appearanceConfig.pinWidth / 2;
  137. self.leftCover.y = _appearanceConfig.borderHeight;
  138. self.leftCover.x = _appearanceConfig.pinWidth;
  139. self.rightCover.height = _appearanceConfig.thumbHeight;
  140. self.rightCover.width = self.width - self.rightPinCenterX - _appearanceConfig.pinWidth/2;
  141. self.rightCover.y = _appearanceConfig.borderHeight;
  142. self.rightCover.x = self.rightPinCenterX - _appearanceConfig.pinWidth/2 + 1;
  143. }
  144. -(CGFloat) getPointDistance:(CGPoint) p1 point2:(CGPoint) p2{
  145. return sqrtf((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
  146. }
  147. #pragma mark - Gestures
  148. -(void)handleGesture:(TCPanGestureRecognizer *)gesture{
  149. if(gesture.state == UIGestureRecognizerStateBegan){
  150. CGFloat d1 = [self getPointDistance:[gesture beginPoint] point2:_leftPin.center];
  151. CGFloat d2 = [self getPointDistance:[gesture beginPoint] point2:_rightPin.center];
  152. CGFloat threshold = 50;
  153. if(d1 < threshold || d2 < threshold){
  154. if(d1 < d2){
  155. dragIdx = 1;
  156. }
  157. else dragIdx = 2;
  158. }
  159. else dragIdx = 0;
  160. }
  161. if(dragIdx == 1){
  162. [self handleLeftPan:gesture];
  163. }
  164. else if(dragIdx == 2){
  165. [self handleRightPan:gesture];
  166. }
  167. if(gesture.state == UIGestureRecognizerStateEnded){
  168. dragIdx = 0;
  169. }
  170. }
  171. - (void)handleLeftPan:(TCPanGestureRecognizer *)gesture
  172. {
  173. CGPoint translation = [gesture translationInView:self];
  174. // NSLog(@"left %f|%f", translation.x, translation.y);
  175. _leftPinCenterX += translation.x;
  176. if (_leftPinCenterX < _appearanceConfig.pinWidth / 2) {
  177. _leftPinCenterX = _appearanceConfig.pinWidth / 2;
  178. }
  179. if (_rightPinCenterX - _leftPinCenterX <= _appearanceConfig.pinWidth) {
  180. _leftPinCenterX = _rightPinCenterX - _appearanceConfig.pinWidth;
  181. }
  182. [gesture setTranslation:CGPointZero inView:[self superview]];
  183. [self setNeedsLayout];
  184. if (gesture.state == UIGestureRecognizerStateBegan) {
  185. if ([self.delegate respondsToSelector:@selector(onRangeLeftChangeBegin:)])
  186. [self.delegate onRangeLeftChangeBegin:self];
  187. }
  188. else if (gesture.state == UIGestureRecognizerStateChanged){
  189. if ([self.delegate respondsToSelector:@selector(onRangeLeftChanged:)])
  190. [self.delegate onRangeLeftChanged:self percent:0];
  191. }
  192. else {
  193. if ([self.delegate respondsToSelector:@selector(onRangeLeftChangeEnded:)])
  194. [self.delegate onRangeLeftChangeEnded:self percent:0];
  195. }
  196. }
  197. - (void)handleRightPan:(UIPanGestureRecognizer *)gesture
  198. {
  199. CGPoint translation = [gesture translationInView:self];
  200. // NSLog(@"right %f|%f", translation.x, translation.y);
  201. _rightPinCenterX += translation.x;
  202. if (_rightPinCenterX > self.width - _appearanceConfig.pinWidth / 2) {
  203. _rightPinCenterX = self.width - _appearanceConfig.pinWidth / 2;
  204. }
  205. if (_rightPinCenterX-_leftPinCenterX <= _appearanceConfig.pinWidth) {
  206. _rightPinCenterX = _leftPinCenterX + _appearanceConfig.pinWidth;
  207. }
  208. [gesture setTranslation:CGPointZero inView:self];
  209. [self setNeedsLayout];
  210. if (gesture.state == UIGestureRecognizerStateBegan) {
  211. if ([self.delegate respondsToSelector:@selector(onRangeRightChangeBegin:)])
  212. [self.delegate onRangeRightChangeBegin:self];
  213. }
  214. else if (gesture.state == UIGestureRecognizerStateChanged) {
  215. if ([self.delegate respondsToSelector:@selector(onRangeRightChanged:)])
  216. [self.delegate onRangeRightChanged:self];
  217. }
  218. else {
  219. if ([self.delegate respondsToSelector:@selector(onRangeRightChangeEnded:)])
  220. [self.delegate onRangeRightChangeEnded:self];
  221. }
  222. }
  223. - (CGFloat)pinWidth
  224. {
  225. return _appearanceConfig.pinWidth;
  226. }
  227. - (CGFloat)imageWidth
  228. {
  229. UIImage *img = self.imageList[0];
  230. if (self.imageList.count == 1) {
  231. return MIN(img.size.width, [UIScreen mainScreen].bounds.size.width - 2 * _appearanceConfig.pinWidth);
  232. }
  233. _imageWidth = img.size.width/img.size.height*_appearanceConfig.thumbHeight;
  234. return _imageWidth;
  235. }
  236. - (CGFloat)imageListWidth {
  237. return self.imageList.count * [self imageWidth];
  238. }
  239. - (CGFloat)leftScale {
  240. return (_leftPinCenterX - _appearanceConfig.pinWidth / 2) / sliderWidth;
  241. }
  242. - (CGFloat)rightScale {
  243. return (_rightPinCenterX - _appearanceConfig.pinWidth / 2 - _appearanceConfig.pinWidth) / sliderWidth;
  244. }
  245. -(void) resetCutView{
  246. _leftPinCenterX = _appearanceConfig.pinWidth / 2;
  247. _rightPinCenterX = self.width - _appearanceConfig.pinWidth / 2;
  248. [self setNeedsLayout];
  249. }
  250. @end
  251. @implementation TCPanGestureRecognizer
  252. -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{
  253. [super touchesBegan:touches withEvent:event];
  254. UITouch* touch = [touches anyObject];
  255. CGPoint point = [touch locationInView:_inView];
  256. _beginPoint = point;
  257. }
  258. -(instancetype)initWithTarget:(id)target action:(SEL)action inview:(UIView*)view{
  259. self= [super initWithTarget:target action:action];
  260. if(self) {
  261. _inView = view;
  262. }
  263. return self;
  264. }
  265. @end