UITableView with UIRefreshControl in a translucent status bar

I created a UITableView that I want to scroll under my translucent black status bar. In my XIB, I just set the table view position y to -20, and everything looks fine.

Now I just added the updated iOS6 UIRefreshControl, which works, however, due to the -20 y position, it is being dragged due to the status bar. I would like the β€œstretched to” position to be below the status bar, not the back.

It makes sense why it will go bad, but there seems to be no difference in changing its frame, but inserting the contents of the table, etc. have no meaning.

The docs assume that after installing refreshControl, the UITableViewController will take care of this place from now on.

Any ideas?

+6
source share
6 answers

You can subclass UIRefreshControl and implement layoutSubviews as follows:

 @implementation RefreshControl { CGFloat topContentInset; BOOL topContentInsetSaved; } - (void)layoutSubviews { [super layoutSubviews]; // getting containing scrollView UIScrollView *scrollView = (UIScrollView *)self.superview; // saving present top contentInset, because it can be changed by refresh control if (!topContentInsetSaved) { topContentInset = scrollView.contentInset.top; topContentInsetSaved = YES; } // saving own frame, that will be modified CGRect newFrame = self.frame; // if refresh control is fully or partially behind UINavigationBar if (scrollView.contentOffset.y + topContentInset > -newFrame.size.height) { // moving it with the rest of the content newFrame.origin.y = -newFrame.size.height; // if refresh control fully appeared } else { // keeping it at the same place newFrame.origin.y = scrollView.contentOffset.y + topContentInset; } // applying new frame to the refresh control self.frame = newFrame; } 

The tableView contentInset taken into account, but you can change the topContentInset variable to whatever value you need, and it will handle the rest.

I hope the code is documented enough to understand how it works.

+9
source

Just subclass UIRefreshControl and override layoutSubviews as follows:

 - (void)layoutSubviews { UIScrollView* parentScrollView = (UIScrollView*)[self superview]; CGSize viewSize = parentScrollView.frame.size; if (parentScrollView.contentInset.top + parentScrollView.contentOffset.y == 0 && !self.refreshing) { self.hidden = YES; } else { self.hidden = NO; } CGFloat y = parentScrollView.contentOffset.y + parentScrollView.scrollIndicatorInsets.top + 20; self.frame = CGRectMake(0, y, viewSize.width, viewSize.height); [super layoutSubviews]; } 
+4
source

the current answer with support does not work very well with the fact that you are pulling out the component (as Anthony Dmitriev pointed out), the offset is incorrect. The last part is to fix it.

In any case: a subclass of UIRefreshControl with the following method:

 - (void)layoutSubviews { UIScrollView* parentScrollView = (UIScrollView*)[self superview]; CGFloat extraOffset = parentScrollView.contentInset.top; CGSize viewSize = parentScrollView.frame.size; if (parentScrollView.contentInset.top + parentScrollView.contentOffset.y == 0 && !self.refreshing) { self.hidden = YES; } else { self.hidden = NO; } CGFloat y = parentScrollView.contentOffset.y + parentScrollView.scrollIndicatorInsets.top + extraOffset; if(y > -60 && !self.isRefreshing){ y = -60; }else if(self.isRefreshing && y <30) { y = y-60; } else if(self.isRefreshing && y >=30) { y = (y-30) -y; } self.frame = CGRectMake(0, y, viewSize.width, viewSize.height); [super layoutSubviews]; } 
+1
source

UIRefreshControl always above the contents of your UITableView . If you need to change the location where refreshControl is installed, try changing the table top to contentInset . UIRefreshControl takes this into account when determining the placement.

0
source

Try the following:

 CGFloat offset = 44; for (UIView *subview in [self subviews]) { if ([subview isKindOfClass:NSClassFromString(@"_UIRefreshControlDefaultContentView")]) { NSLog(@"Setting offset!"); [subview setFrame:CGRectMake(subview.frame.origin.x, subview.frame.origin.y + offset, subview.frame.size.width, subview.frame.size.height)]; } } 

This will move the UIRefreshControll down 44 points;

0
source

I found that redefining layouts in other answers is more than changing a frame, they also change behavior (control began to crawl with content). To change the frame, but not the behavior, I did this:

 - (void)layoutSubviews { [super layoutSubviews]; CGRect frame = self.frame; CGFloat desiredYOffset = 50.0f; self.frame = CGRectMake(frame.origin.x, frame.origin.y + desiredYOffset, frame.size.width, frame.size.height); 

}

0
source

Source: https://habr.com/ru/post/927832/


All Articles