iOS 11: Scroll to top when "adjustedContentInset" changes with larger title bars?

Viewed 4384

I noticed that this code doesn't quite work as expected on iOS 11, because the "adjustedContentInset" property value changes as the "navigationBar" shrinks during a scroll:

CGFloat contentInsetTop=[scrollView contentInset].top;

if (@available(iOS 11.0, *))
{
    contentInsetTop=[scrollView adjustedContentInset].top;

}
////

[scrollView setContentOffset:CGPointMake(0, -contentInsetTop) animated:YES];

... For example, this might start out as 140, then reduce to 88 beyond a minimal scroll offset. This means if you call this, it doesn't actually scroll all the way to the top.

Aside from preserving the original offset in memory from when the UIScrollView loads, is there a way to recover this value later to ensure that it does indeed scroll to top consistently, no matter the "adjustedContentInset"?

2 Answers

Currently, there is indeed no way to do this with iOS 11, I have heard. The only way to do so is to capture the initial value and store it for the life of the navigation/view controller.

I will update my answer accordingly if I hear otherwise, but it will be broken in the base iOS 11 release forever unfortunately.

I had this same problem with a Large Title in iOS 11, and the following code worked for me.

The following code first scrolls the offset a reasonable size above where you want to be. The value -204.666666666667 was the tallest value from setting the Accessibility > Larger Text > Larger Accessibility Sizes to the highest. I'm sure this doesn't cover other possibilities, but it is working for me so far. -CGFloat.greatestFiniteMagnitude is otherwise too problematic.

tableView.setContentOffset(CGPoint(x: 0.0, y: -204.666666666667), animated: false)

This will now give you back the right adjusted content size. To avoid being scrolled too far higher, i.e. leaving white space, just use the value as follows.

var contentOffset = CGPoint.zero // Just setting a variable we can change as needed below, as per iOS version.

if #available(iOS 11, *) {
    contentOffset = CGPoint(x: 0.0, y: -tableView.adjustedContentInset.top)
} else {
    contentOffset = CGPoint(x: 0.0, y: -tableView.contentInset.top)
}

tableView.setContentOffset(contentOffset, animated: false)

In summary, set the offset higher first (-204.666666666667 in my case, or just -300 or whatever), then that readjusts the adjustedContentInset.top to include the Large Title, scroll bar, etc., then you can now set the content offset as needed.

Related