In this following code example self.contentView
refers to the UIScrollView
in question.
// Scroll to bottom.
CGPoint bottomOffset = CGPointMake(0, self.contentView.contentSize.height -
self.contentView.bounds.size.height);
if (bottomOffset.y >= 0.0)
{
[self.contentView setContentOffset:bottomOffset animated:YES];
}
Oddly, in iOS 6 this works perfectly fine, but in iOS 7 the scroll view (assuming it has a contentSize
that's vertically larger than it's frame.size.height
) only scrolls to the very bottom of the bottom most subview added to the scroll view.
For example, if the following cases hold true:
self.contentView.frame.size.height == 50.0
self.contentView.contentSize.height == 100.0
aSubView.frame.origin.y == 50.0
aSubView.frame.size.height == 20.0
The scrolling code will only scroll until aSubView
is visible; self.contentView.contentOffset.y == 20.0
rather than self.contentView.contentOffset.y == 50.0
which would be at the bottom of the entire scroll view.
This is (of course) occurs until programmatically another subview is added to self.contentView
(via a user interaction), then everything corrects itself.
For clarity, I set breakpoints before and after the scrolling code to measure changes to self.contentView.contentOffset
.
Other fun fact, if I remove animated
and set the contentOffset
directly it works as expected on iOS 7, but I'd prefer keeping the animation.
NOTE: Not using interface builder
So I figured out a pretty unsatisfying solution rather quickly by wrapping the call in an async dispatch block.
// Scroll to bottom.
CGPoint bottomOffset = CGPointMake(0, self.contentView.contentSize.height
- self.contentView.bounds.size.height);
if (bottomOffset.y >= 0.0)
{
dispatch_async(dispatch_get_main_queue(), ^{
[self.contentView setContentOffset:bottomOffset animated:YES];
});
}
If anyone understands what is really causing the problem and can provide a better solution I'd gladly accept that as the answer, but for everyone else dealing with the same issue hopefully this works for you as well.