I have UIScrollView with multiple UIVIew subviews. I would like to update the data that is displayed by each UIView when they appear in the visible portion of the UIScrollView.
What is the callback that gets triggered? I tried viewWillAppear, but it does not seem to get called.
Thanks. :)
You have to do the calculation yourself. Implement scrollViewDidScroll:
in your scroll view delegate and calculate manually which views are visible (e.g. by checking if CGRectIntersectsRect(scrollView.bounds, subview.frame)
returns true.
Swift 3 solution
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let viewFrame = greenView.frame
let container = CGRect(x: scrollView.contentOffset.x, y: scrollView.contentOffset.y, width: scrollView.frame.size.width, height: scrollView.frame.size.height)
// We may have received messages while this tableview is offscreen
if (viewFrame.intersects(container)) {
// Do work here
print("view is visible")
}
else{
print("nope view is not on the screen")
}
}
Above answers are correct if your scrollview is not in the zoomed in state. In case if your scrollview can zoom above calculation won't work as you need to consider zoom too
here is the code
CGRect visibleRect;
visibleRect.origin = self.mapScrollView.contentOffset;
visibleRect.size = self.mapScrollView.bounds.size;
float theScale = 1.0 / self.mapScrollView.zoomScale;
visibleRect.origin.x *= theScale;
visibleRect.origin.y *= theScale;
visibleRect.size.width *= theScale;
visibleRect.size.height *= theScale;
if(CGRectIntersectsRect(visibleRect, btnPin.frame)){
...
}
A slight refinement. I wanted to know the amount of the view that was displayed in the scrollview:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
{
// Figure out how much of the self.userFeedbackView is displayed.
CGRect frame = CGRectIntersection(self.scrollView.bounds, self.userFeedbackView.frame);
CGFloat proportion = (frame.size.height*frame.size.width)/(self.userFeedbackView.frameWidth*self.userFeedbackView.frameHeight);
NSLog(@"%f; %@", proportion, NSStringFromCGRect(frame));
}