SDRefreshView.m 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. //
  2. // SDRefreshView.m
  3. // SDRefreshView
  4. //
  5. // Created by aier on 15-2-22.
  6. // Copyright (c) 2015年 GSD. All rights reserved.
  7. //
  8. /**
  9. *******************************************************
  10. * *
  11. * 感谢您的支持, 如果下载的代码在使用过程中出现BUG或者其他问题 *
  12. * 您可以发邮件到gsdios@126.com 或者 到 *
  13. * https://github.com/gsdios?tab=repositories 提交问题 *
  14. * *
  15. *******************************************************
  16. */
  17. #import "SDRefreshView.h"
  18. #import "UIView+SDExtension.h"
  19. CGFloat const SDRefreshViewDefaultHeight = 70.0f;
  20. CGFloat const SDActivityIndicatorViewMargin = 50.0f;
  21. CGFloat const SDTextIndicatorMargin = 20.0f;
  22. CGFloat const SDTimeIndicatorMargin = 10.0f;
  23. @implementation SDRefreshView
  24. {
  25. UIImageView *_stateIndicatorView;
  26. UILabel *_textIndicator;
  27. UILabel *_timeIndicator;
  28. NSString *_lastRefreshingTimeString;
  29. BOOL _hasSetOriginalInsets;
  30. }
  31. - (id)initWithFrame:(CGRect)frame
  32. {
  33. self = [super initWithFrame:frame];
  34. if (self) {
  35. UIActivityIndicatorView *activity = [[UIActivityIndicatorView alloc] init];
  36. activity.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
  37. [activity startAnimating];
  38. [self addSubview:activity];
  39. _activityIndicatorView = activity;
  40. // 状态提示图片
  41. UIImageView *stateIndicator = [[UIImageView alloc] init];
  42. stateIndicator.image = [UIImage imageNamed:@"sdRefeshView_arrow"];
  43. [self addSubview:stateIndicator];
  44. _stateIndicatorView = stateIndicator;
  45. _stateIndicatorView.bounds = CGRectMake(0, 0, 15, 40);
  46. // 状态提示label
  47. UILabel *textIndicator = [[UILabel alloc] init];
  48. textIndicator.bounds = CGRectMake(0, 0, 300, 30);
  49. textIndicator.textAlignment = NSTextAlignmentCenter;
  50. textIndicator.backgroundColor = [UIColor clearColor];
  51. textIndicator.font = [UIFont systemFontOfSize:14];
  52. textIndicator.textColor = [UIColor lightGrayColor];
  53. [self addSubview:textIndicator];
  54. _textIndicator = textIndicator;
  55. // 更新时间提示label
  56. UILabel *timeIndicator = [[UILabel alloc] init];
  57. timeIndicator.bounds = CGRectMake(0, 0, 160, 16);;
  58. timeIndicator.textAlignment = NSTextAlignmentCenter;
  59. timeIndicator.textColor = [UIColor lightGrayColor];
  60. timeIndicator.font = [UIFont systemFontOfSize:14];
  61. [self addSubview:timeIndicator];
  62. _timeIndicator = timeIndicator;
  63. }
  64. return self;
  65. }
  66. + (instancetype)refreshView
  67. {
  68. return [[self alloc] init];
  69. }
  70. - (void)willMoveToSuperview:(UIView *)newSuperview
  71. {
  72. [super willMoveToSuperview:newSuperview];
  73. if (!newSuperview) {
  74. [self.superview removeObserver:self forKeyPath:SDRefreshViewObservingkeyPath];
  75. }
  76. }
  77. - (void)didMoveToSuperview
  78. {
  79. [super didMoveToSuperview];
  80. self.bounds = CGRectMake(0, 0, self.scrollView.frame.size.width, SDRefreshViewDefaultHeight);
  81. }
  82. - (void)layoutSubviews
  83. {
  84. [super layoutSubviews];
  85. _activityIndicatorView.center = CGPointMake(SDActivityIndicatorViewMargin, self.sd_height * 0.5);
  86. _stateIndicatorView.center = _activityIndicatorView.center;
  87. _textIndicator.center = CGPointMake(self.sd_width * 0.5, _activityIndicatorView.sd_height * 0.5 + SDTextIndicatorMargin);
  88. _timeIndicator.center = CGPointMake(self.sd_width * 0.5, self.sd_height - _timeIndicator.sd_height * 0.5 - SDTimeIndicatorMargin);
  89. }
  90. - (NSString *)lastRefreshingTimeString
  91. {
  92. if (_lastRefreshingTimeString == nil) {
  93. return [self refreshingTimeString];
  94. }
  95. return _lastRefreshingTimeString;
  96. }
  97. - (void)addToScrollView:(UIScrollView *)scrollView
  98. {
  99. _scrollView = scrollView;
  100. [_scrollView addSubview:self];
  101. [_scrollView addObserver:self forKeyPath:SDRefreshViewObservingkeyPath options:NSKeyValueObservingOptionNew context:nil];
  102. // 默认是在NavigationController控制下,否则可以调用addToScrollView:isEffectedByNavigationController:(设值为NO) 即可
  103. _isEffectedByNavigationController = YES;
  104. }
  105. - (void)addToScrollView:(UIScrollView *)scrollView isEffectedByNavigationController:(BOOL)effectedByNavigationController
  106. {
  107. [self addToScrollView:scrollView];
  108. _isEffectedByNavigationController = effectedByNavigationController;
  109. _originalEdgeInsets = scrollView.contentInset;
  110. }
  111. - (void)addTarget:(id)target refreshAction:(SEL)action
  112. {
  113. _beginRefreshingTarget = target;
  114. _beginRefreshingAction = action;
  115. }
  116. // 获得在scrollView的contentInset原来基础上增加一定值之后的新contentInset
  117. - (UIEdgeInsets)syntheticalEdgeInsetsWithEdgeInsets:(UIEdgeInsets)edgeInsets
  118. {
  119. return UIEdgeInsetsMake(_originalEdgeInsets.top + edgeInsets.top, _originalEdgeInsets.left + edgeInsets.left, _originalEdgeInsets.bottom + edgeInsets.bottom, _originalEdgeInsets.right + edgeInsets.right);
  120. }
  121. - (void)setRefreshState:(SDRefreshViewState)refreshState
  122. {
  123. _refreshState = refreshState;
  124. switch (refreshState) {
  125. // 进入刷新状态
  126. case SDRefreshViewStateRefreshing:
  127. {
  128. if (!_hasSetOriginalInsets) {
  129. _originalEdgeInsets = self.scrollView.contentInset;
  130. _hasSetOriginalInsets = YES;
  131. }
  132. _scrollView.contentInset = [self syntheticalEdgeInsetsWithEdgeInsets:self.scrollViewEdgeInsets];
  133. [_activityIndicatorView startAnimating];
  134. _stateIndicatorView.hidden = YES;
  135. _activityIndicatorView.hidden = NO;
  136. _lastRefreshingTimeString = [self refreshingTimeString];
  137. _textIndicator.text = SDRefreshViewRefreshingStateText;
  138. if (self.beginRefreshingOperation) {
  139. self.beginRefreshingOperation();
  140. } else if (self.beginRefreshingTarget) {
  141. if ([self.beginRefreshingTarget respondsToSelector:self.beginRefreshingAction]) {
  142. // 屏蔽performSelector-leak警告
  143. #pragma clang diagnostic push
  144. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  145. [self.beginRefreshingTarget performSelector:self.beginRefreshingAction];
  146. }
  147. }
  148. }
  149. break;
  150. case SDRefreshViewStateWillRefresh:
  151. {
  152. _textIndicator.text = SDRefreshViewWillRefreshStateText;
  153. [UIView animateWithDuration:0.5 animations:^{
  154. _stateIndicatorView.transform = CGAffineTransformMakeRotation(self.stateIndicatorViewWillRefreshStateTransformAngle);
  155. }];
  156. }
  157. break;
  158. case SDRefreshViewStateNormal:
  159. {
  160. [UIView animateWithDuration:0.5 animations:^{
  161. _stateIndicatorView.transform = CGAffineTransformMakeRotation(self.stateIndicatorViewNormalTransformAngle);
  162. }];
  163. _textIndicator.text = self.textForNormalState;
  164. _timeIndicator.text = [NSString stringWithFormat:@"最后更新:%@", [self lastRefreshingTimeString]];
  165. _stateIndicatorView.hidden = NO;
  166. [_activityIndicatorView stopAnimating];
  167. _activityIndicatorView.hidden = YES;
  168. }
  169. break;
  170. default:
  171. break;
  172. }
  173. }
  174. - (void)endRefreshing
  175. {
  176. [UIView animateWithDuration:0.6 animations:^{
  177. _scrollView.contentInset = _originalEdgeInsets;
  178. } completion:^(BOOL finished) {
  179. [self setRefreshState:SDRefreshViewStateNormal];
  180. if (self.isManuallyRefreshing) {
  181. self.isManuallyRefreshing = NO;
  182. }
  183. }];
  184. }
  185. // 更新时间
  186. - (NSString *)refreshingTimeString
  187. {
  188. NSDate *date = [NSDate date];
  189. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  190. formatter.dateFormat = @"HH:mm";
  191. return [formatter stringFromDate:date];
  192. }
  193. // 保留!
  194. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
  195. {
  196. ;
  197. }
  198. @end