XLDotLoading.m 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. //
  2. // XLDotLoading.m
  3. // XLDotLoadingDemo
  4. //
  5. // Created by Apple on 2017/1/28.
  6. // Copyright © 2017年 Apple. All rights reserved.
  7. //
  8. #import "XLDotLoading.h"
  9. #import "XLDot.h"
  10. @interface XLDotLoading ()
  11. {
  12. NSMutableArray *_dots;
  13. CADisplayLink *_link;
  14. UIView *_dotContainer;
  15. UILabel *_loadingLabel;
  16. }
  17. @end
  18. @implementation XLDotLoading
  19. //初始化方法
  20. -(instancetype)initWithFrame:(CGRect)frame
  21. {
  22. if (self = [super initWithFrame:frame]) {
  23. [self buildUI];
  24. [self buildData];
  25. }
  26. return self;
  27. }
  28. //豆的宽度
  29. -(CGFloat)dotWidth
  30. {
  31. CGFloat margin = _dotContainer.bounds.size.width/5.0f;
  32. CGFloat dotWidth = (_dotContainer.bounds.size.width - margin)/2.0f;
  33. dotWidth = 15;
  34. return dotWidth;
  35. }
  36. //速度
  37. -(CGFloat)speed
  38. {
  39. return 1.0f;
  40. }
  41. //初始化两个豆
  42. -(void)buildUI
  43. {
  44. //初始化存放豆豆的的容器 豆之间的间距:设置_dotContainer的width
  45. _dotContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 40, 50)];
  46. _dotContainer.center = self.center;
  47. [self addSubview:_dotContainer];
  48. //一个豆放左 一个豆放右
  49. _dots = [NSMutableArray new];
  50. NSArray *dotBackGroundColors = @[[self R:107 G:222 B:209 A:1],[self R:255 G:241 B:0 A:1]];
  51. NSArray *textColors = @[[self R:255 G:197 B:44 A:1],[self R:237 G:215 B:199 A:1]];
  52. for (NSInteger i = 0; i<textColors.count; i++) {
  53. CGFloat dotX = i==0 ? 0 : _dotContainer.bounds.size.width - [self dotWidth];
  54. //初始化开始运动的方向 左边的方向是向右 右边的方向是向左
  55. DotDitection direction = i==0 ? DotDitectionRight : DotDitectionLeft;
  56. XLDot *dot = [[XLDot alloc] initWithFrame:CGRectMake(dotX, 0, [self dotWidth],[self dotWidth])];
  57. dot.center = CGPointMake(dot.center.x, _dotContainer.bounds.size.height/2.0f);
  58. dot.layer.cornerRadius = dot.bounds.size.width/2.0f;
  59. dot.backgroundColor = dotBackGroundColors[i];
  60. dot.direction = direction;
  61. dot.textColor = textColors[i];
  62. [_dotContainer addSubview:dot];
  63. [_dots addObject:dot];
  64. }
  65. _loadingLabel = [[UILabel alloc] initWithFrame:CGRectMake(0,_dotContainer.bounds.origin.y + _dotContainer.bounds.size.height-11 + 10, self.bounds.size.width, 11 +10)];
  66. [self addSubview:_loadingLabel];
  67. _loadingLabel.text = @"正在刷新";
  68. _loadingLabel.textColor = [self R:194 G:194 B:194 A:1];
  69. _loadingLabel.textAlignment = NSTextAlignmentCenter;
  70. _loadingLabel.font = [UIFont systemFontOfSize:11];
  71. }
  72. //初始化定时刷新
  73. -(void)buildData
  74. {
  75. _link = [CADisplayLink displayLinkWithTarget:self selector:@selector(reloadView)];
  76. }
  77. //开始动画
  78. -(void)start
  79. {
  80. [_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
  81. }
  82. //停止动画
  83. -(void)stop
  84. {
  85. [_link removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
  86. }
  87. //刷新UI
  88. -(void)reloadView
  89. {
  90. XLDot *dot1 = _dots.firstObject;
  91. XLDot *dot2 = _dots.lastObject;
  92. //改变移动方向、约束移动范围
  93. //移动到右边距时
  94. if (dot1.center.x >= _dotContainer.bounds.size.width - [self dotWidth]/2.0f) {
  95. CGPoint center = dot1.center;
  96. center.x = _dotContainer.bounds.size.width - [self dotWidth]/2.0f;
  97. dot1.center = center;
  98. dot1.direction = DotDitectionLeft;
  99. dot2.direction = DotDitectionRight;
  100. [_dotContainer bringSubviewToFront:dot1];
  101. }
  102. //移动到左边距时
  103. if (dot1.center.x <= [self dotWidth]/2.0f) {
  104. dot1.center = CGPointMake([self dotWidth]/2.0f, dot2.center.y);
  105. dot1.direction = DotDitectionRight;
  106. dot2.direction = DotDitectionLeft;
  107. [_dotContainer sendSubviewToBack:dot1];
  108. }
  109. //更新第一个豆的位置
  110. CGPoint center1 = dot1.center;
  111. center1.x += dot1.direction * [self speed];
  112. dot1.center = center1;
  113. //显示放大效果
  114. [self showAnimationsOfDot:dot1];
  115. //根据第一个豆的位置确定第二个豆的位置
  116. CGFloat apart = dot1.center.x - _dotContainer.bounds.size.width/2.0f;
  117. CGPoint center2 = dot2.center;
  118. center2.x = _dotContainer.bounds.size.width/2.0f - apart;
  119. dot2.center = center2;
  120. [self showAnimationsOfDot:dot2];
  121. }
  122. //显示放大、缩小动画
  123. -(void)showAnimationsOfDot:(XLDot*)dot
  124. {
  125. CGFloat apart = dot.center.x - _dotContainer.bounds.size.width/2.0f;
  126. //最大距离
  127. CGFloat maxAppart = (_dotContainer.bounds.size.width - [self dotWidth])/2.0f;
  128. //移动距离和最大距离的比例
  129. CGFloat appartScale = apart/maxAppart;
  130. //获取比例对应余弦曲线的Y值
  131. CGFloat transfomscale = cos(appartScale * M_PI/2.0);
  132. //向右移动则 中间变大 两边变小
  133. if (dot.direction == DotDitectionLeft) {
  134. dot.transform = CGAffineTransformMakeScale(1 + transfomscale/4.0f, 1 + transfomscale/4.0f);
  135. //向左移动则 中间变小 两边变大
  136. }else if (dot.direction == DotDitectionRight){
  137. dot.transform = CGAffineTransformMakeScale(1 - transfomscale/4.0f,1 - transfomscale/4.0f);
  138. }
  139. }
  140. -(UIColor*)R:(CGFloat)r G:(CGFloat)g B:(CGFloat)b A:(CGFloat)a
  141. {
  142. return [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a];
  143. }
  144. #pragma mark -
  145. #pragma mark 功能方法
  146. +(XLDotLoading *)getLoadingInView:(UIView *)view {
  147. XLDotLoading *loading = nil;
  148. for (XLDotLoading *subview in view.subviews) {
  149. if ([subview isKindOfClass:[XLDotLoading class]]) {
  150. loading = subview;
  151. }
  152. }
  153. return loading;
  154. }
  155. +(void)showInView:(UIView*)view
  156. {
  157. XLDotLoading *loading = [[XLDotLoading alloc] initWithFrame:view.bounds];
  158. [view addSubview:loading];
  159. [loading start];
  160. }
  161. +(void)hideInView:(UIView *)view
  162. {
  163. XLDotLoading *loading = [XLDotLoading getLoadingInView:view];
  164. if (loading) {
  165. [loading removeFromSuperview];
  166. [loading stop];
  167. }
  168. }
  169. @end