猎豆优选

DCTitleRolling.m 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. //
  2. // DCTitleRolling.m
  3. // CDDTitleRolling
  4. //
  5. // Created by dashen on 2017/11/17.
  6. //Copyright © 2017年 com.RocketsChen. All rights reserved.
  7. //
  8. #define RollingBtnTag 1000
  9. #define RollingViewHeight self.frame.size.height
  10. #define RollingViewWidth self.frame.size.width
  11. #define RollingMargin 10
  12. #import "DCTitleRolling.h"
  13. // Controllers
  14. // Models
  15. // Views
  16. // Vendors
  17. // Categories
  18. #import "UIView+DCRolling.h"
  19. // Others
  20. @interface DCTitleRolling ()
  21. /** 定时器的循环时间 */
  22. @property (nonatomic , assign) NSInteger interval;
  23. /* 定时器 */
  24. @property (strong , nonatomic)NSTimer *timer;
  25. /* 图片 */
  26. @property (strong , nonatomic)NSString *leftImage;
  27. /* 按钮提示文字 */
  28. @property (strong , nonatomic)NSString *rightbuttonTitle;
  29. /* 标题 */
  30. @property (strong , nonatomic)NSArray *rolTitles;
  31. /* tags */
  32. @property (strong , nonatomic)NSArray *rolTags;
  33. /* 右边图片数组 */
  34. @property (strong , nonatomic)NSArray *rightImages;
  35. /* 滚动时间 */
  36. @property (assign , nonatomic)float rollingTime;
  37. /* 字体尺寸 */
  38. @property (nonatomic , assign) NSInteger titleFont;
  39. /* 字体颜色 */
  40. @property (strong , nonatomic)UIColor *titleColor;
  41. /* 滚动按钮数组 */
  42. @property (strong , nonatomic)NSMutableArray *saveMiddleArray;
  43. /** 是否显示tagLabel边框 */
  44. @property (nonatomic,assign)BOOL isShowTagBorder;
  45. @property (nonatomic, assign) CDDRollingGroupStyle rollingGroupStyle;
  46. @end
  47. @implementation DCTitleRolling
  48. #pragma mark - LazyLoad
  49. - (UIImageView *)leftImageView
  50. {
  51. if (!_leftImageView) {
  52. _leftImageView = [[UIImageView alloc] init];
  53. _leftImageView.contentMode = UIViewContentModeCenter;
  54. [self addSubview:_leftImageView];
  55. }
  56. return _leftImageView;
  57. }
  58. - (UIButton *)rightButton
  59. {
  60. if (!_rightButton) {
  61. _rightButton = [UIButton buttonWithType:UIButtonTypeCustom];
  62. _rightButton.adjustsImageWhenHighlighted = NO;
  63. [_rightButton setTitleColor:[UIColor darkGrayColor] forState:0];
  64. [self addSubview:_rightButton];
  65. }
  66. return _rightButton;
  67. }
  68. - (NSMutableArray *)saveMiddleArray
  69. {
  70. if (!_saveMiddleArray) {
  71. _saveMiddleArray = [NSMutableArray array];
  72. }
  73. return _saveMiddleArray;
  74. }
  75. #pragma mark - Intial
  76. - (instancetype)initWithFrame:(CGRect)frame WithTitleData:(void(^)(CDDRollingGroupStyle *rollingGroupStyle, NSString **leftImage,NSArray **rolTitles,NSArray **rolTags,NSArray **rightImages,NSString **rightbuttonTitle,NSInteger *interval,float *rollingTime,NSInteger *titleFont,UIColor **titleColor,BOOL *isShowTagBorder))titleDataBlock{
  77. self = [super initWithFrame:frame];
  78. if (self) {
  79. NSString *leftImage;
  80. NSString *rightbuttonTitle;
  81. NSArray *rolTitles;
  82. NSArray *rolTags;
  83. NSArray *rightImages;
  84. NSInteger interval;
  85. float rollingTime;
  86. NSInteger titleFont;
  87. UIColor *titleColor;
  88. BOOL isShowTagBorder;
  89. if (titleDataBlock) {
  90. titleDataBlock(&_rollingGroupStyle,&leftImage,&rolTitles,&rolTags,&rightImages,&rightbuttonTitle,&interval,&rollingTime,&titleFont,&titleColor,&isShowTagBorder);
  91. self.leftImage = leftImage;
  92. self.rolTitles = rolTitles;
  93. self.rolTags = rolTags;
  94. self.rightImages = rightImages;
  95. self.interval = (interval == 0 || interval > 100) ? 5.0 : interval; //限定定时不大于100秒
  96. self.rollingTime = (rollingTime <= 0.1 || rollingTime > 1) ? 0.5 : rollingTime; //限定翻滚时间不能大于1秒
  97. self.rightbuttonTitle = rightbuttonTitle;
  98. self.titleFont = (titleFont == 0) ? 13 : titleFont;
  99. self.titleColor = (titleColor == nil) ? [UIColor blackColor] : titleColor;
  100. self.isShowTagBorder = isShowTagBorder;
  101. if (self.rolTags.count == 0 && self.rolTitles.count == 0) return 0; //若数组为0直接返回
  102. if (_rollingGroupStyle == CDDRollingTwoGroup) {
  103. [self setUpTwoGroupRollingUI]; //UI
  104. }else{
  105. [self setUpOneGroupRollingUI]; //UI
  106. }
  107. };
  108. }
  109. return self;
  110. }
  111. #pragma mark - 界面搭建【CDDRollingOneGroup】
  112. - (void)setUpOneGroupRollingUI
  113. {
  114. [self setUpRollingLeft];
  115. [self setUpRollingCenter];
  116. [self setUpRollingRight];
  117. }
  118. #pragma mark - 界面搭建【CDDRollingTwoGroup】
  119. - (void)setUpTwoGroupRollingUI
  120. {
  121. [self setUpRollingLeft];
  122. [self setUpRollingCenterRight];
  123. }
  124. #pragma mark - 左边图片
  125. - (void)setUpRollingLeft
  126. {
  127. if (self.leftImage == nil)return;
  128. self.leftImageView.frame = CGRectMake(10, RollingViewHeight * 0.1, RollingViewHeight * 1.5, RollingViewHeight * 0.8);
  129. self.leftImageView.image = [UIImage imageNamed:self.leftImage];
  130. CGSize imgSize = self.leftImageView.image.size;
  131. self.leftImageView.frame = CGRectMake(10, RollingViewHeight * 0.1, imgSize.width, imgSize.height);
  132. self.leftImageView.centerY = self.height/2;
  133. }
  134. #pragma mark - 中间带右部
  135. - (void)setUpRollingCenterRight
  136. {
  137. if (self.saveMiddleArray.count > 0) return;
  138. if (_rolTitles.count > 1) {//@[@[],@[]]
  139. NSArray *firstTitleArrray = _rolTitles.firstObject;
  140. NSArray *firstTagArrray = _rolTags.firstObject;
  141. NSArray *lastTagArray = _rolTags.lastObject;
  142. NSArray *lastTitleArray = _rolTitles.lastObject;
  143. for (NSInteger i= 0; i < firstTitleArrray.count; i++) {
  144. UIButton *middleView = [self getBackMiddleViewWithFrame:CGRectMake(CGRectGetMaxX(self.leftImageView.frame), 0, RollingViewWidth - CGRectGetMaxX(self.leftImageView.frame), RollingViewHeight) WithIndex:i]; //中间View
  145. UILabel *contentTopLabel = [UILabel new];
  146. [middleView addSubview:contentTopLabel];
  147. UILabel *contentBottomLabel = [UILabel new];
  148. [middleView addSubview:contentBottomLabel];
  149. contentTopLabel.textAlignment = contentBottomLabel.textAlignment = NSTextAlignmentLeft;
  150. contentTopLabel.font = contentBottomLabel.font = [UIFont systemFontOfSize:self.titleFont];
  151. contentTopLabel.textColor = contentBottomLabel.textColor = self.titleColor;
  152. UIImageView *rightImageView = [UIImageView new];
  153. if (_rightImages.count == firstTitleArrray.count) {
  154. [middleView addSubview:rightImageView];
  155. rightImageView.frame = CGRectMake(middleView.dc_width - (middleView.dc_height * 1.2), 0, middleView.dc_height * 1.2, middleView.dc_height);
  156. rightImageView.contentMode = UIViewContentModeCenter;
  157. rightImageView.image = [UIImage imageNamed:_rightImages[i]];
  158. }
  159. contentTopLabel.text = firstTitleArrray[i];
  160. contentBottomLabel.text = lastTitleArray[i];
  161. if (_rolTags.count > 0 && firstTitleArrray.count == firstTagArrray.count) {
  162. UILabel *tagTopLabel = [UILabel new];
  163. UILabel *tagBottomLabel = [UILabel new];
  164. [middleView addSubview:tagTopLabel];
  165. [middleView addSubview:tagBottomLabel];
  166. tagTopLabel.font = tagBottomLabel.font = [UIFont systemFontOfSize:self.titleFont - 1.5];
  167. tagTopLabel.textColor = tagBottomLabel.textColor = [UIColor orangeColor];
  168. tagTopLabel.textAlignment = tagBottomLabel.textAlignment = NSTextAlignmentCenter;
  169. tagTopLabel.text = firstTagArrray[i];
  170. tagBottomLabel.text = lastTagArray[i];
  171. if (self.isShowTagBorder) { //是否tag显示边框
  172. [self dc_chageControlCircularWith:tagTopLabel AndSetCornerRadius:3 SetBorderWidth:1 SetBorderColor:tagTopLabel.textColor canMasksToBounds:YES];
  173. [self dc_chageControlCircularWith:tagBottomLabel AndSetCornerRadius:3 SetBorderWidth:1 SetBorderColor:tagBottomLabel.textColor canMasksToBounds:YES];
  174. }
  175. CGSize tagTopSize = [self labelAutoCalculateRectWith:firstTagArrray[i] FontSize:self.titleFont - 1 MaxSize:CGSizeMake(MAXFLOAT, RollingViewHeight)];
  176. CGSize tagBottomSize = [self labelAutoCalculateRectWith:lastTagArray[i] FontSize:self.titleFont - 1 MaxSize:CGSizeMake(MAXFLOAT, RollingViewHeight)];
  177. tagTopLabel.dc_size = CGSizeMake(tagTopSize.width + 4, tagTopSize.height + 4);
  178. tagBottomLabel.dc_size = CGSizeMake(tagBottomSize.width + 4, tagBottomSize.height + 4);
  179. contentTopLabel.frame = CGRectMake(CGRectGetMaxX(tagTopLabel.frame) + 5, 0, middleView.dc_width - rightImageView.dc_width, middleView.dc_height * 0.5);
  180. contentBottomLabel.frame = CGRectMake(CGRectGetMaxX(tagBottomLabel.frame) + 5, middleView.dc_height * 0.5, middleView.dc_width - rightImageView.dc_width, middleView.dc_height * 0.5);
  181. tagTopLabel.dc_x = tagBottomLabel.dc_x = 0;
  182. tagTopLabel.dc_centerY = contentTopLabel.dc_centerY;
  183. tagBottomLabel.dc_centerY = contentBottomLabel.dc_centerY;
  184. }else{
  185. contentTopLabel.frame = CGRectMake(0, 0, middleView.dc_width - rightImageView.dc_width, middleView.dc_height * 0.5);
  186. contentBottomLabel.frame = CGRectMake(0, middleView.dc_height * 0.5, middleView.dc_width - rightImageView.dc_width, middleView.dc_height * 0.5);
  187. }
  188. [self setUpCATransform3DWithIndex:i WithButton:middleView];//旋转
  189. }
  190. }
  191. }
  192. #pragma mark - 中间滚动内容
  193. - (void)setUpRollingCenter
  194. {
  195. if (self.saveMiddleArray.count > 0) return;
  196. if (_rolTitles.count > 0) {
  197. for (NSInteger i = 0; i < _rolTitles.count; i++) {
  198. CGRect middleFrame = (self.rightbuttonTitle == nil) ? CGRectMake(CGRectGetMaxX(self.leftImageView.frame), 0, RollingViewWidth - CGRectGetMaxX(self.leftImageView.frame), RollingViewHeight) : CGRectMake(CGRectGetMaxX(self.leftImageView.frame), 0, RollingViewWidth - (CGRectGetMaxX(self.leftImageView.frame) + RollingViewWidth * 0.2), RollingViewHeight);
  199. UIButton *middleView = [self getBackMiddleViewWithFrame:middleFrame WithIndex:i];
  200. UILabel *contentLabel = [UILabel new];
  201. [middleView addSubview:contentLabel];
  202. contentLabel.textAlignment = NSTextAlignmentLeft;
  203. contentLabel.font = [UIFont systemFontOfSize:self.titleFont];
  204. contentLabel.textColor = self.titleColor;
  205. contentLabel.text = self.rolTitles[i];
  206. if (self.rolTags.count > 0 && self.rolTitles.count == self.rolTags.count) {
  207. UILabel *tagLabel = [UILabel new];
  208. [middleView addSubview:tagLabel];
  209. tagLabel.font = [UIFont systemFontOfSize:self.titleFont - 1.5];
  210. tagLabel.textColor = [UIColor redColor];
  211. tagLabel.textAlignment = NSTextAlignmentCenter;
  212. tagLabel.text = self.rolTags[i];
  213. if (self.isShowTagBorder) {//是否tag显示边框
  214. [self dc_chageControlCircularWith:tagLabel AndSetCornerRadius:3 SetBorderWidth:1 SetBorderColor:tagLabel.textColor canMasksToBounds:YES];
  215. }
  216. CGSize tagSize = [self labelAutoCalculateRectWith:self.rolTags[i] FontSize:self.titleFont - 1 MaxSize:CGSizeMake(MAXFLOAT, RollingViewHeight)];
  217. tagLabel.dc_size = CGSizeMake(tagSize.width + 4, tagSize.height + 4);
  218. tagLabel.dc_x = 0;
  219. tagLabel.dc_centerY = middleView.dc_centerY;
  220. contentLabel.frame = CGRectMake(CGRectGetMaxX(tagLabel.frame) + 5, 0, middleView.dc_width - CGRectGetMaxX(tagLabel.frame), middleView.dc_height);
  221. }else{
  222. contentLabel.frame = CGRectMake(5, 0, middleView.dc_width - RollingMargin, middleView.dc_height);
  223. }
  224. [self setUpCATransform3DWithIndex:i WithButton:middleView]; //旋转
  225. }
  226. }
  227. }
  228. #pragma mark - 右边按钮
  229. - (void)setUpRollingRight
  230. {
  231. if (self.rightbuttonTitle == nil) return;
  232. self.rightButton.frame = CGRectMake(RollingViewWidth * 0.8, RollingViewHeight * 0.1, RollingViewWidth * 0.18, RollingViewHeight * 0.8);
  233. [self.rightButton setTitle:self.rightbuttonTitle forState:0];
  234. self.rightButton.titleLabel.font = [UIFont systemFontOfSize:self.titleFont + 0.5];
  235. [self.rightButton addTarget:self action:@selector(rightMoreButtonClick) forControlEvents:UIControlEventTouchUpInside];
  236. UIView *btnLine = [UIView new];
  237. btnLine.backgroundColor = [UIColor darkGrayColor];
  238. btnLine.frame = CGRectMake(RollingViewWidth * 0.82, RollingViewHeight * 0.35, 1.5, RollingViewHeight * 0.3);
  239. [self addSubview:btnLine];
  240. }
  241. #pragma mark - 开始滚动
  242. - (void)dc_beginRolling{
  243. _timer = [NSTimer timerWithTimeInterval:self.interval target:self selector:@selector(titleRolling) userInfo:nil repeats:YES];
  244. [[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSRunLoopCommonModes];
  245. }
  246. #pragma mark - 结束滚动
  247. - (void)dc_endRolling{
  248. [_timer invalidate];
  249. }
  250. #pragma mark - 标题滚动
  251. - (void)titleRolling{
  252. if (self.saveMiddleArray.count > 1) { //所存的每组滚动
  253. __weak typeof(self)weakSelf = self;
  254. [UIView animateWithDuration:self.rollingTime animations:^{
  255. [self getMiddleArrayWithIndex:0 WithAngle:- M_PI_2 Height:- RollingViewHeight / 2]; //第0组
  256. [self getMiddleArrayWithIndex:1 WithAngle:0 Height:0]; //第一组
  257. } completion:^(BOOL finished) {
  258. if (finished == YES) { //旋转结束
  259. UIButton *newMiddleView = [weakSelf getMiddleArrayWithIndex:0 WithAngle:M_PI_2 Height: -RollingViewHeight / 2];
  260. [weakSelf.saveMiddleArray addObject:newMiddleView];
  261. [weakSelf.saveMiddleArray removeObjectAtIndex:0];
  262. }
  263. }];
  264. }
  265. }
  266. #pragma mark - CATransform3D翻转
  267. - (UIButton *)getMiddleArrayWithIndex:(NSInteger)index WithAngle:(CGFloat)angle Height:(CGFloat)height
  268. {
  269. if (index > _saveMiddleArray.count) return 0;
  270. UIButton *middleView = self.saveMiddleArray[index];
  271. CATransform3D trans = CATransform3DIdentity;
  272. trans = CATransform3DMakeRotation(angle, 1, 0, 0);
  273. trans = CATransform3DTranslate(trans, 0, height, height);
  274. middleView.layer.transform = trans;
  275. return middleView;
  276. }
  277. #pragma mark - 初始布局
  278. - (void)setUpCATransform3DWithIndex:(NSInteger)index WithButton:(UIButton *)contentButton
  279. {
  280. if (index != 0) {
  281. CATransform3D trans = CATransform3DIdentity;
  282. trans = CATransform3DMakeRotation(M_PI_2, 1, 0, 0);
  283. trans = CATransform3DTranslate(trans, 0, - RollingViewHeight / 2, -RollingViewHeight / 2);
  284. contentButton.layer.transform = trans;
  285. }else{
  286. CATransform3D trans = CATransform3DIdentity;
  287. trans = CATransform3DMakeRotation(0, 1, 0, 0);
  288. trans = CATransform3DTranslate(trans, 0, 0, - RollingViewHeight / 2);
  289. contentButton.layer.transform = trans;
  290. }
  291. }
  292. #pragma mark - 初始化中间View
  293. - (UIButton *)getBackMiddleViewWithFrame:(CGRect)frame WithIndex:(NSInteger)index
  294. {
  295. UIButton *middleView = [UIButton buttonWithType:UIButtonTypeCustom];
  296. middleView.adjustsImageWhenHighlighted = NO;
  297. middleView.tag = RollingBtnTag + index;
  298. [middleView addTarget:self action:@selector(titleButonAction:) forControlEvents:UIControlEventTouchUpInside];
  299. middleView.frame = frame;
  300. [self addSubview:middleView];
  301. [self.saveMiddleArray addObject:middleView];
  302. return middleView;
  303. }
  304. #pragma mark - 点击更多
  305. - (void)rightMoreButtonClick
  306. {
  307. !_moreClickBlock ? : _moreClickBlock();
  308. }
  309. - (void)titleButonAction:(UIButton *)sender
  310. {
  311. NSInteger tag = sender.tag - RollingBtnTag;
  312. if ([self.delegate respondsToSelector:@selector(dc_RollingViewSelectWithActionAtIndex:)]) {
  313. [self.delegate dc_RollingViewSelectWithActionAtIndex:tag];
  314. }
  315. }
  316. @end