Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you set the scroll view insets for container controllers?

I have a container controller that displays a bar of data right below the lop layout guide.

I want the child controller of the this container controller to be able to scroll behind this bar as well as any navigation bar and status bar. However it seems that when UIKit automatically adjusts the scroll view insets of a controller it only takes into account the length of the top layout guide.

Is there any way to be say that the scroll view insets should be the top layout guide + the height of my bar? I know people are going to suggest I set automaticallyAdjustsScrollViewInsets = NO but I have already tried this. The problem is that I cannot seem to replicate exactly when UIKit sets the content insets and so I get all sorts of weird edge cases that break the insets. The most prominent example being UITableViewController where, because I set the content insets manually, the refresh control is sometimes not in the correct position and when I end refreshing the insets of the scroll view get set to { 0, 0 } so content is hidden behind my bar and the navigation bar.

UPDATE: All the magic seems to be inside the methods _setNavigationControllerContentInsetAdjustment on UIViewController and _computeAndApplyScrollContentInsetDeltaForViewController on UINavigationController.

It appears that only the navigation controller attempts to adjust the scroll view insets and it calculates the insets based on the top and bottom layout guides. It passes these insets onto the view controller which then adds/subtracts the insets from the scroll view and takes into consideration what navigation content insets have been set previously. This ensures that if anyone else modified the content insets between now and when the navigation controller last modified the insets they will not override the intermediary changes.

like image 784
Reid Main Avatar asked Jun 19 '14 13:06

Reid Main


1 Answers

My solution was to set automaticallyAdjustsScrollViewInsets = NO and handle the setting of the content insets myself.

I created a category on UIViewController that tracked any existing insets that were set so whenever I adjusted the insets to have the scroll view appear below my custom UIView I would not be losing any information, such as the content inset for the UITableViewController with a active refresh control inside it.

After that the last challenge was figuring out where to set the custom insets and after much experimenting I found that - (void)viewDidLayoutSubviews was the best place to do it.

FDScrollingTabBarController is the container controller that I implemented this solution in.

like image 169
Reid Main Avatar answered Oct 30 '22 01:10

Reid Main