diff --git a/MJRefresh.podspec b/MJRefresh.podspec index 00009b7d..fb9ed998 100644 --- a/MJRefresh.podspec +++ b/MJRefresh.podspec @@ -10,4 +10,5 @@ Pod::Spec.new do |s| s.source_files = "MJRefreshExample/MJRefreshExample/MJRefresh/*.{h,m}" s.resource = "MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.bundle" s.requires_arc = true + s.dependency 'SVProgressHUD', '~> 1.1.3' end diff --git a/MJRefreshExample/MJRefreshExample/MJRefresh/MJLDMCircleView.h b/MJRefreshExample/MJRefreshExample/MJRefresh/MJLDMCircleView.h new file mode 100644 index 00000000..9aec7486 --- /dev/null +++ b/MJRefreshExample/MJRefreshExample/MJRefresh/MJLDMCircleView.h @@ -0,0 +1,14 @@ +// +// MJLDMCircleView.h +// Pods +// +// Created by ypchen on 6/24/15. +// +// + +#import + +@interface MJLDMCircleView : UIView +@property (nonatomic) CGFloat progress; +@property (nonatomic) BOOL bNeedClear; +@end diff --git a/MJRefreshExample/MJRefreshExample/MJRefresh/MJLDMCircleView.m b/MJRefreshExample/MJRefreshExample/MJRefresh/MJLDMCircleView.m new file mode 100644 index 00000000..685bb16e --- /dev/null +++ b/MJRefreshExample/MJRefreshExample/MJRefresh/MJLDMCircleView.m @@ -0,0 +1,31 @@ +// +// MJLDMCircleView.m +// Pods +// +// Created by ypchen on 6/24/15. +// +// + +#import "MJLDMCircleView.h" + +@implementation MJLDMCircleView + +- (nonnull instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + self.backgroundColor = [UIColor clearColor]; + } + return self; +} + +- (void)drawRect:(CGRect)rect +{ + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextSetLineWidth(context, 1.0); + CGContextSetLineCap(context, kCGLineCapRound); + CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:0x66/255.0 green:0x66/255.0 blue:0x66/255.0 alpha:1].CGColor); + CGFloat startAngle = -M_PI/2; + CGFloat step = 12*M_PI/6 * self.progress; + CGContextAddArc(context, self.bounds.size.width/2, self.bounds.size.height/2, self.bounds.size.width/2-5, startAngle, startAngle+step, 0); + CGContextStrokePath(context); +} +@end diff --git a/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h b/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h index 987ee397..01f2d0f5 100644 --- a/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h +++ b/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h @@ -9,6 +9,9 @@ #define MJLog(...) #endif +#define DEGREES_TO_RADIANS(x) (x)/180.0*M_PI + + // 过期提醒 #define MJDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead) diff --git a/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.m b/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.m index 9176827d..630246ed 100644 --- a/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.m +++ b/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.m @@ -77,7 +77,7 @@ - (void)setRefreshingImages:(NSArray *)refreshingImages _refreshingImages = refreshingImages; self.gifView.animationImages = refreshingImages; - self.gifView.animationDuration = refreshingImages.count * 0.1; +// self.gifView.animationDuration = refreshingImages.count * 0.1; // 根据图片设置控件的高度 UIImage *image = [refreshingImages firstObject]; diff --git a/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.m b/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.m index ecdf5cc5..07483e81 100644 --- a/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.m +++ b/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.m @@ -82,7 +82,7 @@ - (void)setState:(MJRefreshHeaderState)state self.gifView.image = [images lastObject]; } else { // 多张图片 self.gifView.animationImages = images; - self.gifView.animationDuration = images.count * 0.1; +// self.gifView.animationDuration = images.count * 0.1; [self.gifView startAnimating]; } break; diff --git a/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.m b/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.m index 6c70655d..990794d4 100644 --- a/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.m +++ b/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.m @@ -8,25 +8,36 @@ // #import "MJRefreshLegendFooter.h" +#import "UIScrollView+MJExtension.h" #import "MJRefreshConst.h" #import "UIView+MJExtension.h" -#import "UIScrollView+MJExtension.h" +#import "MJLDMCircleView.h" +#import "SVIndefiniteAnimatedView.h" @interface MJRefreshLegendFooter() -@property (nonatomic, weak) UIActivityIndicatorView *activityView; +@property (nonatomic, strong) SVIndefiniteAnimatedView *activityView; @end @implementation MJRefreshLegendFooter -#pragma mark - 懒加载 -- (UIActivityIndicatorView *)activityView -{ + +#pragma mark - lazy load + +- (SVIndefiniteAnimatedView *)activityView { if (!_activityView) { - UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; - [self addSubview:_activityView = activityView]; + _activityView = [[SVIndefiniteAnimatedView alloc] initWithFrame:CGRectZero]; + _activityView.strokeThickness = 1.0f; + _activityView.strokeColor = [UIColor colorWithRed:0x66/255.0 green:0x66/255.0 blue:0x66/255.0 alpha:1]; + _activityView.radius = 10.0f; + _activityView.center = self.center; + _activityView.alpha = 0.0; + [_activityView sizeToFit]; + [self addSubview:_activityView]; + [self bringSubviewToFront:_activityView]; } return _activityView; } + #pragma mark - 初始化方法 - (void)layoutSubviews { @@ -47,15 +58,16 @@ - (void)setState:(MJRefreshFooterState)state switch (state) { case MJRefreshFooterStateIdle: - [self.activityView stopAnimating]; + + self.activityView.alpha = .0f; break; case MJRefreshFooterStateRefreshing: - [self.activityView startAnimating]; + self.activityView.alpha = 1.0f; break; case MJRefreshFooterStateNoMoreData: - [self.activityView stopAnimating]; + self.activityView.alpha = .0f; break; default: diff --git a/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.m b/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.m index 3349b137..5a8acfe5 100644 --- a/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.m +++ b/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.m @@ -10,29 +10,55 @@ #import "MJRefreshLegendHeader.h" #import "MJRefreshConst.h" #import "UIView+MJExtension.h" +#import "MJLDMCircleView.h" +#import "SVIndefiniteAnimatedView.h" +#import "MJRefreshConst.h" @interface MJRefreshLegendHeader() @property (nonatomic, weak) UIImageView *arrowImage; -@property (nonatomic, weak) UIActivityIndicatorView *activityView; +@property (nonatomic, strong) SVIndefiniteAnimatedView *activityView; +@property (nonatomic, strong) CALayer *imageLayer; +@property (nonatomic) CGFloat progress; + +@property (nonatomic, strong) MJLDMCircleView *circleView; @end @implementation MJRefreshLegendHeader -#pragma mark - 懒加载 + +#pragma mark - lazy load - (UIImageView *)arrowImage { if (!_arrowImage) { - UIImageView *arrowImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:MJRefreshSrcName(@"arrow.png")]]; + UIImageView *arrowImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"pull_refresh_arrow"]]; [self addSubview:_arrowImage = arrowImage]; } + self.imageLayer = _arrowImage.layer; + self.imageLayer.hidden = NO; + self.imageLayer.transform = CATransform3DMakeRotation(DEGREES_TO_RADIANS(0),0,0,1); return _arrowImage; } -- (UIActivityIndicatorView *)activityView -{ +- (MJLDMCircleView *)circleView { + if (!_circleView) { + _circleView = [[MJLDMCircleView alloc] initWithFrame:CGRectZero]; + _circleView.clearsContextBeforeDrawing = YES; + self.circleView.alpha = 1.0; + [self addSubview:_circleView]; + } + return _circleView; +} + +- (SVIndefiniteAnimatedView *)activityView { if (!_activityView) { - UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; - activityView.bounds = self.arrowImage.bounds; - [self addSubview:_activityView = activityView]; + _activityView = [[SVIndefiniteAnimatedView alloc] initWithFrame:CGRectZero]; + _activityView.strokeThickness = 1.0f; + _activityView.strokeColor = [UIColor colorWithRed:0x66/255.0 green:0x66/255.0 blue:0x66/255.0 alpha:1]; + _activityView.radius = 10.0f; + _activityView.center = self.center; + _activityView.alpha = 0.0; + [_activityView sizeToFit]; + [self addSubview:_activityView]; + [self bringSubviewToFront:_activityView]; } return _activityView; } @@ -45,11 +71,44 @@ - (void)layoutSubviews // 箭头 CGFloat arrowX = (self.stateHidden && self.updatedTimeHidden) ? self.mj_w * 0.5 : (self.mj_w * 0.5 - 100); self.arrowImage.center = CGPointMake(arrowX, self.mj_h * 0.5); + self.circleView.bounds = CGRectMake(0, 0, 30, 30); + self.circleView.center = self.arrowImage.center; // 指示器 + self.activityView.bounds = CGRectMake(0, 0, 30, 30); self.activityView.center = self.arrowImage.center; + } +- (void)setProgress:(CGFloat)progress { + _progress = progress; + + static CGFloat prevProgress; + + if(progress > 1.0) { + progress = 1.0; + } + + if (progress >= 0 && progress <=1.0) { + CABasicAnimation *animationImage = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; + animationImage.fromValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(360*prevProgress)]; + animationImage.toValue = [NSNumber numberWithFloat:DEGREES_TO_RADIANS(360*progress)]; + animationImage.duration = 0.15; + animationImage.removedOnCompletion = NO; + animationImage.fillMode = kCAFillModeForwards; + [self.imageLayer addAnimation:animationImage forKey:@"arrow_rotation"]; + + [self.circleView setProgress:progress]; + [self.circleView setNeedsDisplay]; + } + prevProgress = progress; +} + +- (void)setPullingPercent:(CGFloat)pullingPercent +{ + [super setPullingPercent:pullingPercent]; + [self setProgress:pullingPercent]; +} #pragma mark - 公共方法 #pragma mark 设置状态 - (void)setState:(MJRefreshHeaderState)state @@ -62,33 +121,29 @@ - (void)setState:(MJRefreshHeaderState)state switch (state) { case MJRefreshHeaderStateIdle: { if (oldState == MJRefreshHeaderStateRefreshing) { - self.arrowImage.transform = CGAffineTransformIdentity; - - [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ - self.activityView.alpha = 0.0; - } completion:^(BOOL finished) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJRefreshSlowAnimationDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + self.pullingPercent = 0.0; self.arrowImage.alpha = 1.0; - self.activityView.alpha = 1.0; - [self.activityView stopAnimating]; - }]; + self.activityView.alpha = 0.0; + self.circleView.alpha = 1.0; + }); } else { - [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ - self.arrowImage.transform = CGAffineTransformIdentity; - }]; + self.pullingPercent = self.pullingPercent; } + break; } case MJRefreshHeaderStatePulling: { - [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ - self.arrowImage.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); - }]; + self.circleView.alpha = 1.0; + self.activityView.alpha = 0.0; break; } case MJRefreshHeaderStateRefreshing: { - [self.activityView startAnimating]; + self.activityView.alpha = 1.0; self.arrowImage.alpha = 0.0; + self.circleView.alpha = 0.0; break; } @@ -101,3 +156,5 @@ - (void)setState:(MJRefreshHeaderState)state } @end + + diff --git "a/MJRefreshScreenshots/UICollectionView01-\344\270\212\344\270\213\346\213\211\345\210\267\346\226\260.gif" "b/MJRefreshScreenshots/UICollectionView01-\344\270\212\344\270\213\346\213\211\345\210\267\346\226\260.gif" deleted file mode 100644 index 3f92efe7..00000000 Binary files "a/MJRefreshScreenshots/UICollectionView01-\344\270\212\344\270\213\346\213\211\345\210\267\346\226\260.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26001-\344\274\240\347\273\237.gif" "b/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26001-\344\274\240\347\273\237.gif" deleted file mode 100644 index cb4924b1..00000000 Binary files "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26001-\344\274\240\347\273\237.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26002-\345\212\250\347\224\273\345\233\276\347\211\207.gif" "b/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26002-\345\212\250\347\224\273\345\233\276\347\211\207.gif" deleted file mode 100644 index 76f5bc99..00000000 Binary files "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26002-\345\212\250\347\224\273\345\233\276\347\211\207.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26003-\351\232\220\350\227\217\347\212\266\346\200\20101.gif" "b/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26003-\351\232\220\350\227\217\347\212\266\346\200\20101.gif" deleted file mode 100644 index 8398442b..00000000 Binary files "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26003-\351\232\220\350\227\217\347\212\266\346\200\20101.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26004-\351\232\220\350\227\217\347\212\266\346\200\20102.gif" "b/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26004-\351\232\220\350\227\217\347\212\266\346\200\20102.gif" deleted file mode 100644 index 1f9a3a36..00000000 Binary files "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26004-\351\232\220\350\227\217\347\212\266\346\200\20102.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26005-\345\205\250\351\203\250\345\212\240\350\275\275\345\256\214\346\257\225.gif" "b/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26005-\345\205\250\351\203\250\345\212\240\350\275\275\345\256\214\346\257\225.gif" deleted file mode 100644 index 83619bf8..00000000 Binary files "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26005-\345\205\250\351\203\250\345\212\240\350\275\275\345\256\214\346\257\225.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26006-\347\246\201\346\255\242\350\207\252\345\212\250\345\212\240\350\275\275.gif" "b/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26006-\347\246\201\346\255\242\350\207\252\345\212\250\345\212\240\350\275\275.gif" deleted file mode 100644 index 9b7e4de9..00000000 Binary files "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26006-\347\246\201\346\255\242\350\207\252\345\212\250\345\212\240\350\275\275.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26007-\350\207\252\345\256\232\344\271\211\346\226\207\345\255\227.gif" "b/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26007-\350\207\252\345\256\232\344\271\211\346\226\207\345\255\227.gif" deleted file mode 100644 index 0e30f56b..00000000 Binary files "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26007-\350\207\252\345\256\232\344\271\211\346\226\207\345\255\227.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26008-\345\212\240\350\275\275\345\220\216\351\232\220\350\227\217.gif" "b/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26008-\345\212\240\350\275\275\345\220\216\351\232\220\350\227\217.gif" deleted file mode 100644 index 03dc9ed3..00000000 Binary files "a/MJRefreshScreenshots/\344\270\212\346\213\211\345\210\267\346\226\26008-\345\212\240\350\275\275\345\220\216\351\232\220\350\227\217.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26001-\344\274\240\347\273\237.gif" "b/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26001-\344\274\240\347\273\237.gif" deleted file mode 100644 index e637a2a8..00000000 Binary files "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26001-\344\274\240\347\273\237.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26002-\345\212\250\347\224\273\345\233\276\347\211\207.gif" "b/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26002-\345\212\250\347\224\273\345\233\276\347\211\207.gif" deleted file mode 100644 index de1edcbf..00000000 Binary files "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26002-\345\212\250\347\224\273\345\233\276\347\211\207.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26003-\351\232\220\350\227\217\346\227\266\351\227\264.gif" "b/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26003-\351\232\220\350\227\217\346\227\266\351\227\264.gif" deleted file mode 100644 index c0ab50c4..00000000 Binary files "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26003-\351\232\220\350\227\217\346\227\266\351\227\264.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26004-\351\232\220\350\227\217\347\212\266\346\200\201\345\222\214\346\227\266\351\227\26401.gif" "b/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26004-\351\232\220\350\227\217\347\212\266\346\200\201\345\222\214\346\227\266\351\227\26401.gif" deleted file mode 100644 index bb66e5b0..00000000 Binary files "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26004-\351\232\220\350\227\217\347\212\266\346\200\201\345\222\214\346\227\266\351\227\26401.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26005-\351\232\220\350\227\217\347\212\266\346\200\201\345\222\214\346\227\266\351\227\26402.gif" "b/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26005-\351\232\220\350\227\217\347\212\266\346\200\201\345\222\214\346\227\266\351\227\26402.gif" deleted file mode 100644 index 6ab6607d..00000000 Binary files "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26005-\351\232\220\350\227\217\347\212\266\346\200\201\345\222\214\346\227\266\351\227\26402.gif" and /dev/null differ diff --git "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26006-\350\207\252\345\256\232\344\271\211\346\226\207\345\255\227.gif" "b/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26006-\350\207\252\345\256\232\344\271\211\346\226\207\345\255\227.gif" deleted file mode 100644 index f5284377..00000000 Binary files "a/MJRefreshScreenshots/\344\270\213\346\213\211\345\210\267\346\226\26006-\350\207\252\345\256\232\344\271\211\346\226\207\345\255\227.gif" and /dev/null differ