Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UITableView pull to refresh causing flickering. How to prevent it?

I'm doing that pull-down-to-refresh thing. In scrollViewDidEndDecelerating I check if the offset is past a certain point and in scrollViewDidEndDragging I set the contentInset so as to keep the pulled-down section visible.

However, this results in flickering, probably due to the contentInset being reset during scrolling animation. I thought I might be able to prevent this by setting the targetContentOffset in scrollViewWillEndDragging, but it doesn't seem to do the trick.

 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 
{

     if (scrollView.contentOffset.y < -kRefreshViewDelta) 
     {
         self.tableView.contentInset = UIEdgeInsetsMake(kRefreshViewHeight, 0.0f, 0.0f, 0.0f);

     }
}

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
 {
     if (scrollView.contentOffset.y  < -kRefreshViewDelta) 
     {
          targetContentOffset->y = kRefreshViewHeight ;
     }
 }
like image 272
akaru Avatar asked Feb 27 '12 01:02

akaru


2 Answers

If you change the frame assigned to the UITableView at all (during the scrolling or otherwise), it will cause the contentInset to be reset to the default (0,0,0,0). There is some state checking for mine, but essentially this is what I've done for mine...

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView
                  willDecelerate:(BOOL)decelerate {
  if (scrollView.contentOffset.y < -kRefreshDeltaY) {
    animation = ^{
        [self setContentInset:UIEdgeInsetsMake(kRefreshDeltaY,
                                                          0, 0, 0)];
    };

    [UIView animateWithDuration:0.3
                          delay:0
                        options:UIViewAnimationOptionAllowUserInteraction
                     animations:animation
                     completion:completion];
  } // if
}

As long as I didn't lay out subviews or change the frame of the UITableView, it behaved fine for me.

like image 125
Mike Welsh Avatar answered Oct 22 '22 11:10

Mike Welsh


Mike's answer worked for me (but I couldn't up-vote or comment on it). It appears that wrapping my code in the animation block eliminated the flicker for me.

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 
{
    if (scrollView.contentOffset.y < 0 && scrollView.contentInset.top < 0)
    {
        // shows table header view
        // setting inset without using animation block causes flicker
        [UIView animateWithDuration:0.1 animations:^
        {
            scrollView.contentInset = UIEdgeInsetsZero;
        }];
    }

    // hides table header view
    if (scrollView.contentOffset.y > 44 && scrollView.contentInset.top == 0)
    {
        scrollView.contentInset = UIEdgeInsetsMake(-44, 0, 0, 0);
    }
}
like image 33
sc0rp10n Avatar answered Oct 22 '22 09:10

sc0rp10n