RangeContent.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. //
  2. // VideoRangeContent.m
  3. // SAVideoRangeSliderExample
  4. //
  5. // Created by annidyfeng on 2017/4/18.
  6. // Copyright © 2017年 Andrei Solovjev. All rights reserved.
  7. //
  8. #import "RangeContent.h"
  9. #import "UIView+Additions.h"
  10. #import "VideoRangeConst.h"
  11. @implementation RangeContentConfig
  12. - (id)init
  13. {
  14. if (self = [super init]) {
  15. _pinWidth = PIN_WIDTH;
  16. _thumbHeight = THUMB_HEIGHT;
  17. _borderHeight = BORDER_HEIGHT;
  18. _leftPinImage = [UIImage imageNamed:@"left"];
  19. _centerPinImage = [UIImage imageNamed:@"center"];
  20. _rightPigImage = [UIImage imageNamed:@"right"];
  21. }
  22. return self;
  23. }
  24. @end
  25. @interface RangeContent()
  26. @end
  27. @implementation RangeContent {
  28. CGFloat _imageWidth;
  29. RangeContentConfig* _appearanceConfig;
  30. }
  31. - (instancetype)initWithImageList:(NSArray *)images
  32. {
  33. _imageList = images;
  34. _appearanceConfig = [RangeContentConfig 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:(RangeContentConfig *)config
  41. {
  42. _imageList = images;
  43. _appearanceConfig = config;
  44. CGRect frame = {.origin = CGPointZero, .size = [self intrinsicContentSize]};
  45. self = [super initWithFrame:frame];
  46. [self iniSubViews];
  47. return self;
  48. }
  49. - (void)iniSubViews
  50. {
  51. CGRect frame = self.bounds;
  52. NSMutableArray *tmpList = [NSMutableArray new];
  53. for (int i = 0; i < _imageList.count; i++) {
  54. CGRect imgFrame = CGRectMake(_appearanceConfig.pinWidth + i*[self imageWidth],
  55. _appearanceConfig.borderHeight,
  56. [self imageWidth],
  57. _appearanceConfig.thumbHeight);
  58. UIImageView *imgView = [[UIImageView alloc] initWithFrame:imgFrame];
  59. imgView.clipsToBounds = YES;
  60. imgView.image = _imageList[i];
  61. imgView.contentMode = (_imageList.count > 1 ? UIViewContentModeScaleAspectFill : UIViewContentModeScaleAspectFit);
  62. [self addSubview:imgView];
  63. [tmpList addObject:imgView];
  64. }
  65. _imageViewList = tmpList;
  66. // self.centerCover = ({
  67. // UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
  68. // [self addSubview:view];
  69. // view.userInteractionEnabled = YES;
  70. // UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleCenterPan:)];
  71. // [view addGestureRecognizer:panGes];
  72. // view.accessibilityIdentifier = @"center";
  73. // view;
  74. // });
  75. if (_appearanceConfig.leftCorverImage) {
  76. self.leftCover = [[UIImageView alloc] initWithImage:_appearanceConfig.leftCorverImage];
  77. self.leftCover.contentMode = UIViewContentModeCenter;
  78. self.leftCover.clipsToBounds = YES;
  79. }
  80. else {
  81. self.leftCover = [[UIImageView alloc] initWithFrame:CGRectZero];
  82. self.leftCover.backgroundColor = [UIColor blackColor];
  83. self.leftCover.alpha = 0.5;
  84. };
  85. [self addSubview:self.leftCover];
  86. if (_appearanceConfig.rightCoverImage) {
  87. self.rightCover = [[UIImageView alloc] initWithImage:_appearanceConfig.rightCoverImage];
  88. self.rightCover.contentMode = UIViewContentModeCenter;
  89. self.rightCover.clipsToBounds = YES;
  90. }
  91. else {
  92. self.rightCover = [[UIImageView alloc] initWithFrame:CGRectZero];
  93. self.rightCover.backgroundColor = [UIColor blackColor];
  94. self.rightCover.alpha = 0.5;
  95. }
  96. [self addSubview:self.rightCover];
  97. self.leftPin = ({
  98. UIImageView *imageView = [[UIImageView alloc] initWithImage:_appearanceConfig.leftPinImage];
  99. imageView.contentMode = UIViewContentModeScaleToFill;
  100. imageView.width = _appearanceConfig.pinWidth;
  101. imageView.height = _appearanceConfig.thumbHeight + 2 * _appearanceConfig.borderHeight;
  102. [self addSubview:imageView];
  103. imageView.userInteractionEnabled = YES;
  104. UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftPan:)];
  105. [imageView addGestureRecognizer:panGes];
  106. imageView;
  107. });
  108. self.centerPin = ({
  109. UIImageView *imageView = [[UIImageView alloc] initWithImage:_appearanceConfig.centerPinImage];
  110. imageView.contentMode = UIViewContentModeScaleToFill;
  111. imageView.width = PIN_WIDTH;
  112. imageView.height = _appearanceConfig.thumbHeight + 2 * _appearanceConfig.borderHeight;
  113. [self addSubview:imageView];
  114. imageView.userInteractionEnabled = YES;
  115. UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleCenterPan:)];
  116. [imageView addGestureRecognizer:panGes];
  117. imageView;
  118. });
  119. self.centerPin.hidden = YES;
  120. self.rightPin = ({
  121. UIImageView *imageView = [[UIImageView alloc] initWithImage:_appearanceConfig.rightPigImage];
  122. imageView.contentMode = UIViewContentModeScaleToFill;
  123. imageView.width = _appearanceConfig.pinWidth;
  124. imageView.height = _appearanceConfig.thumbHeight + 2 * _appearanceConfig.borderHeight;
  125. [self addSubview:imageView];
  126. imageView.userInteractionEnabled = YES;
  127. UIPanGestureRecognizer *panGes = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightPan:)];
  128. [imageView addGestureRecognizer:panGes];
  129. imageView;
  130. });
  131. self.topBorder = ({
  132. UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
  133. [self addSubview:view];
  134. view.backgroundColor = [UIColor colorWithRed:239 / 255.0 green:100 / 255.0 blue:85 / 255.0 alpha:1];
  135. view;
  136. });
  137. self.bottomBorder = ({
  138. UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
  139. [self addSubview:view];
  140. view.backgroundColor = [UIColor colorWithRed:239 / 255.0 green:100 / 255.0 blue:85 / 255.0 alpha:1];
  141. view;
  142. });
  143. _leftPinCenterX = _appearanceConfig.pinWidth / 2;
  144. _centerPinCenterX = frame.size.width / 2;
  145. _rightPinCenterX = frame.size.width- _appearanceConfig.pinWidth / 2;
  146. }
  147. - (CGSize)intrinsicContentSize {
  148. return CGSizeMake([self imageWidth] * self.imageList.count + 2 * _appearanceConfig.pinWidth, _appearanceConfig.thumbHeight + 2 * _appearanceConfig.borderHeight);
  149. }
  150. - (void)layoutSubviews {
  151. [super layoutSubviews];
  152. self.leftPin.center = CGPointMake(self.leftPinCenterX, self.height / 2);
  153. self.centerPin.center = CGPointMake(self.centerPinCenterX, self.height / 2);
  154. self.rightPin.center = CGPointMake(self.rightPinCenterX, self.height / 2);
  155. [self unpdateBorder];
  156. self.centerCover.height = _appearanceConfig.thumbHeight - 2 * _appearanceConfig.borderHeight;
  157. self.centerCover.width = self.rightPinCenterX - self.leftPinCenterX - _appearanceConfig.pinWidth;
  158. self.centerCover.y = _appearanceConfig.borderHeight;
  159. self.centerCover.x = self.leftPinCenterX + _appearanceConfig.pinWidth / 2;
  160. self.leftCover.height = _appearanceConfig.thumbHeight;
  161. self.leftCover.width = self.leftPinCenterX;
  162. self.leftCover.y = _appearanceConfig.borderHeight;
  163. self.leftCover.x = 0;
  164. self.rightCover.height = _appearanceConfig.thumbHeight;
  165. self.rightCover.width = self.width - self.rightPinCenterX;
  166. self.rightCover.y = _appearanceConfig.borderHeight;
  167. self.rightCover.x = self.rightPinCenterX;
  168. }
  169. - (void)unpdateBorder
  170. {
  171. self.topBorder.height = _appearanceConfig.borderHeight;
  172. self.topBorder.width = self.rightPinCenterX - self.leftPinCenterX - _appearanceConfig.pinWidth;
  173. self.topBorder.y = 0;
  174. self.topBorder.x = self.leftPinCenterX + _appearanceConfig.pinWidth / 2;
  175. self.bottomBorder.height = _appearanceConfig.borderHeight;
  176. self.bottomBorder.width = self.rightPinCenterX - self.leftPinCenterX - _appearanceConfig.pinWidth;
  177. self.bottomBorder.y = self.leftPin.bottom-_appearanceConfig.borderHeight;
  178. self.bottomBorder.x = self.leftPinCenterX + _appearanceConfig.pinWidth / 2;
  179. }
  180. #pragma mark - Gestures
  181. - (void)handleLeftPan:(UIPanGestureRecognizer *)gesture
  182. {
  183. if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged || gesture.state == UIGestureRecognizerStateEnded) {
  184. CGPoint translation = [gesture translationInView:self];
  185. _leftPinCenterX += translation.x;
  186. if (_leftPinCenterX < _appearanceConfig.pinWidth / 2) {
  187. _leftPinCenterX = _appearanceConfig.pinWidth / 2;
  188. }
  189. if (_centerPin.isHidden){
  190. if (_rightPinCenterX - _leftPinCenterX <= _appearanceConfig.pinWidth) {
  191. _leftPinCenterX = _rightPinCenterX - _appearanceConfig.pinWidth;
  192. }
  193. }else{
  194. if (_centerPinCenterX - _leftPinCenterX <= _appearanceConfig.pinWidth) {
  195. _leftPinCenterX = _centerPinCenterX - _appearanceConfig.pinWidth;
  196. }
  197. }
  198. [gesture setTranslation:CGPointZero inView:self];
  199. [self setNeedsLayout];
  200. if (gesture.state == UIGestureRecognizerStateBegan) {
  201. if ([self.delegate respondsToSelector:@selector(onRangeLeftChangeBegin:)])
  202. [self.delegate onRangeLeftChangeBegin:self];
  203. }
  204. else if (gesture.state == UIGestureRecognizerStateChanged){
  205. if ([self.delegate respondsToSelector:@selector(onRangeLeftChanged:)])
  206. [self.delegate onRangeLeftChanged:self];
  207. }
  208. else {
  209. if ([self.delegate respondsToSelector:@selector(onRangeLeftChangeEnded:)])
  210. [self.delegate onRangeLeftChangeEnded:self];
  211. }
  212. }
  213. }
  214. - (void)handleCenterPan:(UIPanGestureRecognizer *)gesture
  215. {
  216. if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged || gesture.state == UIGestureRecognizerStateEnded) {
  217. CGPoint translation = [gesture translationInView:self];
  218. _centerPinCenterX += translation.x;
  219. if (_centerPinCenterX < _appearanceConfig.pinWidth) {
  220. _centerPinCenterX = _appearanceConfig.pinWidth;
  221. }
  222. if (_centerPinCenterX > self.width - _appearanceConfig.pinWidth) {
  223. _centerPinCenterX = self.width - _appearanceConfig.pinWidth;
  224. }
  225. [gesture setTranslation:CGPointZero inView:self];
  226. [self setNeedsLayout];
  227. if (gesture.state == UIGestureRecognizerStateBegan) {
  228. if ([self.delegate respondsToSelector:@selector(onRangeCenterChangeBegin:)])
  229. [self.delegate onRangeCenterChangeBegin:self];
  230. }
  231. else if (gesture.state == UIGestureRecognizerStateChanged){
  232. if ([self.delegate respondsToSelector:@selector(onRangeCenterChanged:)])
  233. [self.delegate onRangeCenterChanged:self];
  234. }
  235. else {
  236. if ([self.delegate respondsToSelector:@selector(onRangeCenterChangeEnded:)])
  237. [self.delegate onRangeCenterChangeEnded:self];
  238. }
  239. }
  240. }
  241. - (void)handleRightPan:(UIPanGestureRecognizer *)gesture
  242. {
  243. if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged || gesture.state == UIGestureRecognizerStateEnded) {
  244. CGPoint translation = [gesture translationInView:self];
  245. _rightPinCenterX += translation.x;
  246. if (_rightPinCenterX > self.width - _appearanceConfig.pinWidth / 2) {
  247. _rightPinCenterX = self.width - _appearanceConfig.pinWidth / 2;
  248. }
  249. if (_centerPin.isHidden) {
  250. if (_rightPinCenterX-_leftPinCenterX <= _appearanceConfig.pinWidth) {
  251. _rightPinCenterX = _leftPinCenterX + _appearanceConfig.pinWidth;
  252. }
  253. }else{
  254. if (_rightPinCenterX-_centerPinCenterX <= _appearanceConfig.pinWidth) {
  255. _rightPinCenterX = _centerPinCenterX + _appearanceConfig.pinWidth;
  256. }
  257. }
  258. [gesture setTranslation:CGPointZero inView:self];
  259. [self setNeedsLayout];
  260. if (gesture.state == UIGestureRecognizerStateBegan) {
  261. if ([self.delegate respondsToSelector:@selector(onRangeRightChangeBegin:)])
  262. [self.delegate onRangeRightChangeBegin:self];
  263. }
  264. else if (gesture.state == UIGestureRecognizerStateChanged) {
  265. if ([self.delegate respondsToSelector:@selector(onRangeRightChanged:)])
  266. [self.delegate onRangeRightChanged:self];
  267. }
  268. else {
  269. if ([self.delegate respondsToSelector:@selector(onRangeRightChangeEnded:)])
  270. [self.delegate onRangeRightChangeEnded:self];
  271. }
  272. }
  273. }
  274. //- (void)handleCenterPan:(UIPanGestureRecognizer *)gesture
  275. //{
  276. //
  277. // if (gesture.state == UIGestureRecognizerStateBegan || gesture.state == UIGestureRecognizerStateChanged) {
  278. //
  279. // CGPoint translation = [gesture translationInView:self];
  280. //
  281. // _leftPinCenterX += translation.x;
  282. // _rightPinCenterX += translation.x;
  283. //
  284. // if (_rightPinCenterX > self.width - _appearanceConfig.pinWidth || _leftPinCenterX < _appearanceConfig.pinWidth / 2){
  285. // _leftPinCenterX -= translation.x;
  286. // _rightPinCenterX -= translation.x;
  287. // }
  288. //
  289. // [gesture setTranslation:CGPointZero inView:self];
  290. //
  291. // [self setNeedsLayout];
  292. //
  293. // if ([self.delegate respondsToSelector:@selector(onRangeLeftAndRightChanged:)])
  294. // [self.delegate onRangeLeftAndRightChanged:self];
  295. //
  296. // }
  297. //}
  298. - (CGFloat)pinWidth
  299. {
  300. return _appearanceConfig.pinWidth;
  301. }
  302. - (CGFloat)imageWidth
  303. {
  304. UIImage *img = self.imageList[0];
  305. if (self.imageList.count == 1) {
  306. return MIN(img.size.width, [UIScreen mainScreen].bounds.size.width - 2 * _appearanceConfig.pinWidth);
  307. }
  308. _imageWidth = img.size.width/img.size.height*_appearanceConfig.thumbHeight;
  309. return _imageWidth;
  310. }
  311. - (CGFloat)imageListWidth {
  312. return self.imageList.count * [self imageWidth];
  313. }
  314. - (CGFloat)leftScale {
  315. CGFloat imagesLength = [self imageWidth] * self.imageViewList.count;
  316. return MAX(0, (_leftPinCenterX - _appearanceConfig.pinWidth / 2) / imagesLength);
  317. }
  318. - (CGFloat)rightScale {
  319. CGFloat imagesLength = [self imageWidth] * self.imageViewList.count;
  320. return MAX(0, (_rightPinCenterX - _appearanceConfig.pinWidth / 2 - _appearanceConfig.pinWidth) / imagesLength);
  321. }
  322. - (CGFloat)centerScale {
  323. CGFloat imagesLength = [self imageWidth] * self.imageViewList.count;
  324. return MAX(0, (_centerPinCenterX - _appearanceConfig.pinWidth / 2 - _appearanceConfig.pinWidth) / imagesLength);
  325. }
  326. @end