From 3fe36a0931ab5af4de2374ce5d69cf998d61f767 Mon Sep 17 00:00:00 2001 From: jangwonhee Date: Thu, 14 Apr 2016 10:40:36 +0900 Subject: [PATCH 1/6] sync --- Class/BarItem.m | 15 +++-- Class/CBStoreHouseRefreshControl.h | 3 +- Class/CBStoreHouseRefreshControl.m | 102 +++++++++++++++++++---------- 3 files changed, 79 insertions(+), 41 deletions(-) diff --git a/Class/BarItem.m b/Class/BarItem.m index 0e7a57f..642a857 100644 --- a/Class/BarItem.m +++ b/Class/BarItem.m @@ -24,17 +24,18 @@ - (instancetype)initWithFrame:(CGRect)frame startPoint:(CGPoint)startPoint endPo { self = [super initWithFrame:frame]; if (self) { - _startPoint = startPoint; - _endPoint = endPoint; - _lineWidth = lineWidth; - _color = color; + self.startPoint = startPoint; + self.endPoint = endPoint; + self.lineWidth = lineWidth; + self.color = color; + self.backgroundColor = [UIColor clearColor]; CGPoint (^middlePoint)(CGPoint, CGPoint) = ^CGPoint(CGPoint a, CGPoint b) { CGFloat x = (a.x + b.x)/2.f; CGFloat y = (a.y + b.y)/2.f; return CGPointMake(x, y); }; - _middlePoint = middlePoint(startPoint, endPoint); + self.middlePoint = middlePoint(startPoint, endPoint); } return self; } @@ -54,10 +55,10 @@ - (void)setHorizontalRandomness:(int)horizontalRandomness dropHeight:(CGFloat)dr - (void)drawRect:(CGRect)rect { UIBezierPath* bezierPath = UIBezierPath.bezierPath; - [bezierPath moveToPoint:self.startPoint]; - [bezierPath addLineToPoint:self.endPoint]; [self.color setStroke]; bezierPath.lineWidth = self.lineWidth; + [bezierPath moveToPoint:self.startPoint]; + [bezierPath addLineToPoint:self.endPoint]; [bezierPath stroke]; } diff --git a/Class/CBStoreHouseRefreshControl.h b/Class/CBStoreHouseRefreshControl.h index 01692c9..91bb2e8 100644 --- a/Class/CBStoreHouseRefreshControl.h +++ b/Class/CBStoreHouseRefreshControl.h @@ -25,7 +25,8 @@ scale:(CGFloat)scale horizontalRandomness:(CGFloat)horizontalRandomness reverseLoadingAnimation:(BOOL)reverseLoadingAnimation - internalAnimationFactor:(CGFloat)internalAnimationFactor; + internalAnimationFactor:(CGFloat)internalAnimationFactor + invert:(BOOL)invert; - (void)scrollViewDidScroll; diff --git a/Class/CBStoreHouseRefreshControl.m b/Class/CBStoreHouseRefreshControl.m index 9a32d13..7501fed 100644 --- a/Class/CBStoreHouseRefreshControl.m +++ b/Class/CBStoreHouseRefreshControl.m @@ -12,8 +12,8 @@ static const CGFloat kloadingIndividualAnimationTiming = 0.8; static const CGFloat kbarDarkAlpha = 0.4; static const CGFloat kloadingTimingOffset = 0.1; -static const CGFloat kdisappearDuration = 1.2; -static const CGFloat krelativeHeightFactor = 2.f/5.f; +static const CGFloat kdisappearDuration = 0.5f; +static const CGFloat krelativeHeightFactor = 0.5f; typedef enum { CBStoreHouseRefreshControlStateIdle = 0, @@ -29,27 +29,27 @@ @interface CBStoreHouseRefreshControl () @property (nonatomic) CBStoreHouseRefreshControlState state; -@property (nonatomic, weak) UIScrollView *scrollView; +@property (nonatomic, strong) UIScrollView *scrollView; @property (nonatomic, strong) NSArray *barItems; @property (nonatomic, strong) CADisplayLink *displayLink; @property (nonatomic, assign) id target; @property (nonatomic) SEL action; @property (nonatomic) CGFloat dropHeight; -@property (nonatomic) CGFloat originalTopContentInset; @property (nonatomic) CGFloat disappearProgress; @property (nonatomic) CGFloat internalAnimationFactor; @property (nonatomic) int horizontalRandomness; @property (nonatomic) BOOL reverseLoadingAnimation; +@property (nonatomic) BOOL invert; @end @implementation CBStoreHouseRefreshControl + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView - target:(id)target - refreshAction:(SEL)refreshAction - plist:(NSString *)plist + target:(id)target + refreshAction:(SEL)refreshAction + plist:(NSString *)plist { return [CBStoreHouseRefreshControl attachToScrollView:scrollView target:target @@ -61,7 +61,8 @@ + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView scale:1 horizontalRandomness:150 reverseLoadingAnimation:NO - internalAnimationFactor:0.7]; + internalAnimationFactor:0.7 + invert:NO]; } + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView @@ -75,6 +76,7 @@ + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView horizontalRandomness:(CGFloat)horizontalRandomness reverseLoadingAnimation:(BOOL)reverseLoadingAnimation internalAnimationFactor:(CGFloat)internalAnimationFactor + invert:(BOOL)invert { CBStoreHouseRefreshControl *refreshControl = [[CBStoreHouseRefreshControl alloc] init]; refreshControl.dropHeight = dropHeight; @@ -86,6 +88,9 @@ + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView refreshControl.internalAnimationFactor = internalAnimationFactor; [scrollView addSubview:refreshControl]; + refreshControl.invert = invert; + + // Calculate frame according to points max width and height CGFloat width = 0; CGFloat height = 0; @@ -103,17 +108,16 @@ + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView if (endPoint.y > height) height = endPoint.y; } refreshControl.frame = CGRectMake(0, 0, width, height); - + // Create bar items NSMutableArray *mutableBarItems = [[NSMutableArray alloc] init]; for (int i=0; i self.dropHeight) { + if (self.animationProgress == 1) self.state = CBStoreHouseRefreshControlStateRefreshing; + } if (self.state == CBStoreHouseRefreshControlStateRefreshing) { UIEdgeInsets newInsets = self.scrollView.contentInset; - newInsets.top = self.originalTopContentInset + self.dropHeight; + if(self.invert) { + newInsets.bottom += self.dropHeight; + } else { + newInsets.top += self.dropHeight; + } CGPoint contentOffset = self.scrollView.contentOffset; + self.scrollView.contentInset = newInsets; + self.scrollView.contentOffset = contentOffset; - [UIView animateWithDuration:0 animations:^(void) { - self.scrollView.contentInset = newInsets; - self.scrollView.contentOffset = contentOffset; - }]; - - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" if ([self.target respondsToSelector:self.action]) [self.target performSelector:self.action withObject:self]; - #pragma clang diagnostic pop +#pragma clang diagnostic pop [self startLoadingAnimation]; } @@ -176,12 +204,15 @@ - (void)scrollViewDidEndDragging - (CGFloat)animationProgress { + if(self.invert) { + return MIN(1.f, MAX(0, fabsf(self.scrollView.contentSize.height - (self.realContentOffsetY - self.scrollView.contentInset.top) - self.scrollView.frame.size.height)/self.dropHeight)); + } return MIN(1.f, MAX(0, fabsf(self.realContentOffsetY)/self.dropHeight)); } - (CGFloat)realContentOffsetY { - return self.scrollView.contentOffset.y + self.originalTopContentInset; + return self.scrollView.contentOffset.y + self.scrollView.contentInset.top; } - (void)updateBarItemsWithProgress:(CGFloat)progress @@ -245,7 +276,7 @@ - (void)barItemAnimation:(BarItem*)barItem isLastOne = barItem.tag == 0; else isLastOne = barItem.tag == self.barItems.count-1; - + if (isLastOne && self.state == CBStoreHouseRefreshControlStateRefreshing) { [self startLoadingAnimation]; } @@ -266,16 +297,21 @@ - (void)updateDisappearAnimation - (void)finishingLoading { self.state = CBStoreHouseRefreshControlStateDisappearing; - UIEdgeInsets newInsets = self.scrollView.contentInset; - newInsets.top = self.originalTopContentInset; [UIView animateWithDuration:kdisappearDuration animations:^(void) { + UIEdgeInsets newInsets = self.scrollView.contentInset; + if(self.invert) { + newInsets.bottom -= self.dropHeight; + } else { + newInsets.top -= self.dropHeight; + } + self.scrollView.contentInset = newInsets; } completion:^(BOOL finished) { self.state = CBStoreHouseRefreshControlStateIdle; [self.displayLink invalidate]; self.disappearProgress = 1; }]; - + for (BarItem *barItem in self.barItems) { [barItem.layer removeAllAnimations]; barItem.alpha = kbarDarkAlpha; From bb2f06cf695e05fe13e7418a5df9ade2ee151967 Mon Sep 17 00:00:00 2001 From: jangwonhee Date: Thu, 14 Apr 2016 11:35:14 +0900 Subject: [PATCH 2/6] sync --- Class/CBStoreHouseRefreshControl.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Class/CBStoreHouseRefreshControl.m b/Class/CBStoreHouseRefreshControl.m index 7501fed..ed3e0d1 100644 --- a/Class/CBStoreHouseRefreshControl.m +++ b/Class/CBStoreHouseRefreshControl.m @@ -179,9 +179,9 @@ - (void)scrollViewDidEndDragging UIEdgeInsets newInsets = self.scrollView.contentInset; if(self.invert) { - newInsets.bottom += self.dropHeight; + newInsets.bottom += self.realContentOffsetY + self.scrollView.frame.size.height - self.scrollView.contentSize.height; } else { - newInsets.top += self.dropHeight; + newInsets.top += self.realContentOffsetY; } CGPoint contentOffset = self.scrollView.contentOffset; self.scrollView.contentInset = newInsets; From 0a6b227568aaf6e5a9fc4eccbb104970d04abf75 Mon Sep 17 00:00:00 2001 From: jangwonhee Date: Thu, 14 Apr 2016 11:41:27 +0900 Subject: [PATCH 3/6] .. --- .../ContentViewController.m | 2 +- Class/CBStoreHouseRefreshControl.m | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CBStoreHouseRefreshControl/ContentViewController.m b/CBStoreHouseRefreshControl/ContentViewController.m index dced6ad..d9beae3 100644 --- a/CBStoreHouseRefreshControl/ContentViewController.m +++ b/CBStoreHouseRefreshControl/ContentViewController.m @@ -35,7 +35,7 @@ - (void)viewDidLoad { self.tableView.tableFooterView = footer; // Let the show begins - self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"storehouse" color:[UIColor whiteColor] lineWidth:1.5 dropHeight:80 scale:1 horizontalRandomness:150 reverseLoadingAnimation:YES internalAnimationFactor:0.5]; + self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"storehouse" color:[UIColor whiteColor] lineWidth:1.5 dropHeight:80 scale:1 horizontalRandomness:150 reverseLoadingAnimation:YES internalAnimationFactor:0.5 invert:NO]; //self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"AKTA" color:[UIColor whiteColor] lineWidth:2 dropHeight:80 scale:0.7 horizontalRandomness:300 reverseLoadingAnimation:NO internalAnimationFactor:0.7]; } diff --git a/Class/CBStoreHouseRefreshControl.m b/Class/CBStoreHouseRefreshControl.m index ed3e0d1..5da7838 100644 --- a/Class/CBStoreHouseRefreshControl.m +++ b/Class/CBStoreHouseRefreshControl.m @@ -12,7 +12,7 @@ static const CGFloat kloadingIndividualAnimationTiming = 0.8; static const CGFloat kbarDarkAlpha = 0.4; static const CGFloat kloadingTimingOffset = 0.1; -static const CGFloat kdisappearDuration = 0.5f; +static const CGFloat kDuration = 0.5f; static const CGFloat krelativeHeightFactor = 0.5f; typedef enum { @@ -179,13 +179,15 @@ - (void)scrollViewDidEndDragging UIEdgeInsets newInsets = self.scrollView.contentInset; if(self.invert) { - newInsets.bottom += self.realContentOffsetY + self.scrollView.frame.size.height - self.scrollView.contentSize.height; + newInsets.bottom += self.dropHeight; } else { - newInsets.top += self.realContentOffsetY; + newInsets.top += self.dropHeight; } CGPoint contentOffset = self.scrollView.contentOffset; - self.scrollView.contentInset = newInsets; - self.scrollView.contentOffset = contentOffset; + [UIView animateWithDuration:kDuration animations:^(void) { + self.scrollView.contentInset = newInsets; + self.scrollView.contentOffset = contentOffset; + }]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" @@ -286,7 +288,7 @@ - (void)barItemAnimation:(BarItem*)barItem - (void)updateDisappearAnimation { if (self.disappearProgress >= 0 && self.disappearProgress <= 1) { - self.disappearProgress -= 1/60.f/kdisappearDuration; + self.disappearProgress -= 1/60.f/kDuration; //60.f means this method get called 60 times per second [self updateBarItemsWithProgress:self.disappearProgress]; } @@ -297,7 +299,7 @@ - (void)updateDisappearAnimation - (void)finishingLoading { self.state = CBStoreHouseRefreshControlStateDisappearing; - [UIView animateWithDuration:kdisappearDuration animations:^(void) { + [UIView animateWithDuration:kDuration animations:^(void) { UIEdgeInsets newInsets = self.scrollView.contentInset; if(self.invert) { newInsets.bottom -= self.dropHeight; From b6a28c407d65fa0d9499ab7df1dbe77f6bc24531 Mon Sep 17 00:00:00 2001 From: jangwonhee Date: Thu, 14 Apr 2016 12:37:17 +0900 Subject: [PATCH 4/6] .. --- .../ContentViewController.m | 10 ++----- Class/CBStoreHouseRefreshControl.m | 26 ++++++++++++++----- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/CBStoreHouseRefreshControl/ContentViewController.m b/CBStoreHouseRefreshControl/ContentViewController.m index d9beae3..ae09335 100644 --- a/CBStoreHouseRefreshControl/ContentViewController.m +++ b/CBStoreHouseRefreshControl/ContentViewController.m @@ -24,18 +24,12 @@ - (void)viewDidLoad { self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]}; - self.tableView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"bg_pattern"]]; - self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - self.tableView.backgroundColor = [UIColor colorWithWhite:45.f/255.f alpha:1]; [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"]; self.tableView.alwaysBounceVertical = YES; - - UIView *footer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, self.tableView.bounds.size.height)]; - self.tableView.tableFooterView = footer; // Let the show begins - self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"storehouse" color:[UIColor whiteColor] lineWidth:1.5 dropHeight:80 scale:1 horizontalRandomness:150 reverseLoadingAnimation:YES internalAnimationFactor:0.5 invert:NO]; + self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"storehouse" color:[UIColor blackColor] lineWidth:1.5 dropHeight:60 scale:0.8 horizontalRandomness:150 reverseLoadingAnimation:YES internalAnimationFactor:0.5 invert:YES]; //self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"AKTA" color:[UIColor whiteColor] lineWidth:2 dropHeight:80 scale:0.7 horizontalRandomness:300 reverseLoadingAnimation:NO internalAnimationFactor:0.7]; } @@ -59,7 +53,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return 1; + return 2; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath diff --git a/Class/CBStoreHouseRefreshControl.m b/Class/CBStoreHouseRefreshControl.m index 5da7838..7c70221 100644 --- a/Class/CBStoreHouseRefreshControl.m +++ b/Class/CBStoreHouseRefreshControl.m @@ -147,15 +147,16 @@ + (CBStoreHouseRefreshControl*)attachToScrollView:(UIScrollView *)scrollView - (void)scrollViewDidScroll { +// printf("%f\n",[self bottomDrop]); if (self.state == CBStoreHouseRefreshControlStateRefreshing) { if (self.invert) { - self.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, self.scrollView.contentSize.height+self.dropHeight*krelativeHeightFactor); + self.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, self.scrollView.contentSize.height+[self bottomDrop]*krelativeHeightFactor); } else { self.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, (self.realContentOffsetY-self.dropHeight)*krelativeHeightFactor); } } else { if (self.invert) { - self.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, self.scrollView.contentSize.height+self.dropHeight*krelativeHeightFactor); + self.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, self.scrollView.contentSize.height+[self bottomDrop]*krelativeHeightFactor); } else { self.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, self.realContentOffsetY*krelativeHeightFactor); } @@ -165,28 +166,39 @@ - (void)scrollViewDidScroll [self updateBarItemsWithProgress:self.animationProgress]; } +- (CGFloat)bottomDrop { + return (self.realContentOffsetY + self.scrollView.frame.size.height - self.scrollView.contentSize.height-self.scrollView.contentInset.top); +} + - (void)scrollViewDidEndDragging { if (self.state == CBStoreHouseRefreshControlStateIdle) { if(self.invert == NO && self.realContentOffsetY < -self.dropHeight) { if (self.animationProgress == 1) self.state = CBStoreHouseRefreshControlStateRefreshing; } - if(self.invert == YES && self.realContentOffsetY + self.scrollView.frame.size.height - self.scrollView.contentSize.height > self.dropHeight) { + if(self.invert == YES && [self bottomDrop] > self.dropHeight) { if (self.animationProgress == 1) self.state = CBStoreHouseRefreshControlStateRefreshing; } if (self.state == CBStoreHouseRefreshControlStateRefreshing) { UIEdgeInsets newInsets = self.scrollView.contentInset; + UIEdgeInsets curInset = self.scrollView.contentInset; if(self.invert) { newInsets.bottom += self.dropHeight; + curInset.bottom += [self bottomDrop]; } else { newInsets.top += self.dropHeight; + curInset.top -= self.scrollView.contentOffset.y; } - CGPoint contentOffset = self.scrollView.contentOffset; - [UIView animateWithDuration:kDuration animations:^(void) { + + self.scrollView.contentInset = curInset; + [self.scrollView setNeedsLayout]; + [UIView animateWithDuration:kDuration animations:^{ + self.scrollView.bounces = NO; self.scrollView.contentInset = newInsets; - self.scrollView.contentOffset = contentOffset; + } completion:^(BOOL finished) { + self.scrollView.bounces = YES; }]; #pragma clang diagnostic push @@ -307,8 +319,10 @@ - (void)finishingLoading newInsets.top -= self.dropHeight; } + self.scrollView.bounces = NO; self.scrollView.contentInset = newInsets; } completion:^(BOOL finished) { + self.scrollView.bounces = YES; self.state = CBStoreHouseRefreshControlStateIdle; [self.displayLink invalidate]; self.disappearProgress = 1; From 78967d745ce5290115635233e8fc1a842aacc511 Mon Sep 17 00:00:00 2001 From: jangwonhee Date: Thu, 14 Apr 2016 13:43:08 +0900 Subject: [PATCH 5/6] sync --- CBStoreHouseRefreshControl/ContentViewController.m | 2 +- Class/CBStoreHouseRefreshControl.m | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CBStoreHouseRefreshControl/ContentViewController.m b/CBStoreHouseRefreshControl/ContentViewController.m index ae09335..727c499 100644 --- a/CBStoreHouseRefreshControl/ContentViewController.m +++ b/CBStoreHouseRefreshControl/ContentViewController.m @@ -29,7 +29,7 @@ - (void)viewDidLoad { self.tableView.alwaysBounceVertical = YES; // Let the show begins - self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"storehouse" color:[UIColor blackColor] lineWidth:1.5 dropHeight:60 scale:0.8 horizontalRandomness:150 reverseLoadingAnimation:YES internalAnimationFactor:0.5 invert:YES]; + self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"storehouse" color:[UIColor blackColor] lineWidth:1.5 dropHeight:60 scale:0.8 horizontalRandomness:150 reverseLoadingAnimation:YES internalAnimationFactor:0.5 invert:NO]; //self.storeHouseRefreshControl = [CBStoreHouseRefreshControl attachToScrollView:self.tableView target:self refreshAction:@selector(refreshTriggered:) plist:@"AKTA" color:[UIColor whiteColor] lineWidth:2 dropHeight:80 scale:0.7 horizontalRandomness:300 reverseLoadingAnimation:NO internalAnimationFactor:0.7]; } diff --git a/Class/CBStoreHouseRefreshControl.m b/Class/CBStoreHouseRefreshControl.m index 7c70221..88d1a71 100644 --- a/Class/CBStoreHouseRefreshControl.m +++ b/Class/CBStoreHouseRefreshControl.m @@ -189,7 +189,6 @@ - (void)scrollViewDidEndDragging curInset.bottom += [self bottomDrop]; } else { newInsets.top += self.dropHeight; - curInset.top -= self.scrollView.contentOffset.y; } self.scrollView.contentInset = curInset; From 5b223ae538663f807dcbd7b5122d6e7a627767a5 Mon Sep 17 00:00:00 2001 From: jangwonhee Date: Fri, 15 Apr 2016 00:37:05 +0900 Subject: [PATCH 6/6] sync --- Class/CBStoreHouseRefreshControl.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Class/CBStoreHouseRefreshControl.m b/Class/CBStoreHouseRefreshControl.m index 88d1a71..0d60f13 100644 --- a/Class/CBStoreHouseRefreshControl.m +++ b/Class/CBStoreHouseRefreshControl.m @@ -309,6 +309,9 @@ - (void)updateDisappearAnimation - (void)finishingLoading { + if (self.state != CBStoreHouseRefreshControlStateRefreshing) { + return; + } self.state = CBStoreHouseRefreshControlStateDisappearing; [UIView animateWithDuration:kDuration animations:^(void) { UIEdgeInsets newInsets = self.scrollView.contentInset;