I implemeted a custom refresh control (my own class, not a subclass), and for some reason since moving to iOS 8, setting the contentInset of the scroll view (specifically, UICollectionView) to start the refresh animation causes a weird jump/stutter. Here is my code:
- (void)containingScrollViewDidScroll:(UIScrollView *)scrollView { CGFloat scrollPosition = scrollView.contentOffset.y + scrollView.contentInset.top; if( scrollPosition > 0 || self.isRefreshing ) { return; } CGFloat percentWidth = fabs( scrollPosition ) / self.frame.size.height / 2; CGRect maskFrame = self.maskLayer.frame; maskFrame.size.width = self.imageLayer.frame.size.width * percentWidth; [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; self.maskLayer.frame = maskFrame; [CATransaction commit]; } - (void)containingScrollViewDidEndDragging:(UIScrollView *)scrollView { if( ( self.maskLayer.frame.size.width >= self.imageLayer.frame.size.width ) && !self.isRefreshing ) { self.isRefreshing = YES; [self setLoadingScrollViewInsets:scrollView]; [self startAnimation]; [self sendActionsForControlEvents:UIControlEventValueChanged]; } } - (void)setLoadingScrollViewInsets:(UIScrollView *)scrollView { UIEdgeInsets loadingInset = scrollView.contentInset; loadingInset.top += self.frame.size.height; UIViewAnimationOptions options = UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState; [UIView animateWithDuration:0.2 delay:0 options:options animations:^ { scrollView.contentInset = loadingInset; } completion:nil]; }
Basically once the user releases to refresh, I animate the contentInset to the height of the refresh control. I figure the animation would reduce stuttering/jumpiness, which it did in iOS 7. But in iOS 8, when the scrollView is released from dragging, instead of just animating to the contentInset, the scroll view content jumps down from the point of release really quickly, and then animates up smoothly. I'm not sure if this is a bug in iOS 8 or what. I've also tried adding:
scrollView.contentOffset = CGPointZero;
in the animation block, which didn't change anything.
Does anyone have any ideas? Any help would be highly appreciated. Thanks!
I changed the method with my animation block to:
- (void)setLoadingScrollViewInsets:(UIScrollView *)scrollView { UIEdgeInsets loadingInset = scrollView.contentInset; loadingInset.top += self.view.frame.size.height; CGPoint contentOffset = scrollView.contentOffset; [UIView animateWithDuration:0.2 animations:^ { scrollView.contentInset = loadingInset; scrollView.contentOffset = contentOffset; }]; }
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ CGPoint point = scrollView.contentOffset; static CGFloat refreshViewHeight = 200.0f; if (scrollView.contentInset.top == refreshViewHeight) { //openning if (point.y>-refreshViewHeight) { //will close //必须套两层animation才能避免闪动! [UIView animateWithDuration:0 animations:NULL completion:^(BOOL finished) { [UIView animateWithDuration:0.25 animations:^{ scrollView.contentOffset = CGPointMake(0.0f, 0.0f); scrollView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, 0.0f, 0.0f); } completion:NULL]; }]; } } else{ //closing static CGFloat openCriticalY = 40.0f;//会执行打开的临界值 if(point.y<-openCriticalY){ //will open [UIView animateWithDuration:0 animations:NULL completion:^(BOOL finished) { [UIView animateWithDuration:0.25 animations:^{ scrollView.contentInset = UIEdgeInsetsMake(refreshViewHeight, 0.0f, 0.0f, 0.0f); scrollView.contentOffset = CGPointMake(0.0f, -refreshViewHeight); } completion:NULL]; }]; } } }
you can try this,the key is using two animation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With