I have a UIScrollView (actually a UICollectionView, but that probably doesn't matter). When it appears in IOS 7, the navigation controller sets its contentInset and contentOffset to values I don't want. It appears to be trying to adjust for the status bar and the navigation bar. I'd greatly prefer it left them alone. I've fixed this by overriding the getter and setter methods for contentInset and contentOffset, with a flag to tell the object whether or not it should accept a set. But is there a better way?
7 Answers
Try setting self.automaticallyAdjustsScrollViewInsets = NO
in your main view controller.
This was introduced in iOS 7
so you might want to wrap that with an iOS version check, if you are supporting iOS 6
and below.
Update
If you are using storyboards, you can do this in the Interface Builder as well as by checking 'Adjust Scroll View Insets'
for your selected controller.
-
7You can set it on IB only if you are using storyboards. – jerrygdm Oct 02 '13 at 08:57
-
The cruel thing is that IB shows this configuration not correct; even with this flag on, it is displayed in the IB as with flag off.. and if you then start the simulator, the flag works as expected, which confuses you completely -.- An evil setting! :-) – Ursin Brunner Feb 21 '14 at 13:32
-
I‘ve spent a day to figure out why my ImageView is not left-top corner centered with my scrollView. After I turned off this option, all works ! – Zhenyi Zhang Apr 30 '16 at 06:48
-
1What does this "Adjust Scroll View Insets" option even do? – Yakiv Kovalskyi Nov 17 '16 at 14:48
-
@KDaker - I'm in the same boat as Yakiv... this solved my problem (thank you!!!) but I'd like to know what that option is doing in the first place and haven't found any good info elsewhere. Thanks! – Spencer Aug 15 '17 at 14:31
I had a similar problem, after dismissing a viewController, the contentOffset from my tableView was changed to (0, -64).
my solution was a little weird, I tried all the other answers but had no success, the only thing that fixed my problem was to switch the tableView position in the controls tree of the .xib
it was the first control in the parent View like this:
I moved the tableView right after the ImageView and it worked:
it seems that putting the table view in the first position was causing the trouble, and moving the table view to another position fixed the problem.
P.D. I'm not using autoLayout neither storyboards
hope this can help someone!

- 2,391
- 1
- 30
- 29
-
-
2You're a star! Never thought the order of the scrollview can be the problem. – Andrew L. Jun 12 '14 at 03:35
-
4The reason this occurs is hinted at by the accepted answer. The UIViewController will automatically set the contentInset of the first UIView. By making the UITableView the second view, it won't get it's contentInset automatically set. – Michael McGuire Jun 13 '14 at 15:27
-
Michael, unfortunately not true. In my case controller property was not checked (false) and still I got weird inset. Event changing insets to 0 in viewWillAppear was not helping. But moving it in view hierarchy helped. Really weird error. – Michał Hernas Nov 05 '14 at 16:10
-
Thank you! I never would have found that, I actually had to add an empty view to the ViewController for this fix. – Buyin Brian Sep 03 '15 at 16:40
-
Wow, that is bizarre, i have same problem, fixable by adding a dummy view. – user1055568 Dec 15 '16 at 20:30
I have two solutions:
1.
self.view = scrollView;
2.
[self.navigationController.toolbar setTranslucent:NO];

- 992
- 8
- 10
-
1Thanks for this, Instead of `toolbar` in your second example I needed `NavigationBar` as in `navigationController.NavigationBar.Translucent = false;` (note: Xamarin) which worked. – ta.speot.is May 01 '15 at 05:14
I'm having the same problem.
Setting
self.automaticallyAdjustsScrollViewInsets = NO
solved the issue for some of the view but not everywhere.Second solution is to set the content-offset of tableview/view/scrollview in viewWillLayoutSubviews:
- (void)viewWillLayoutSubviews { //Arrange the view CGRect tempViewFrame = self.view.frame; if (tempViewFrame.origin.y == 64.0f) { tempViewFrame.origin.y = 0; self.view.frame = tempViewFrame; } }

- 7,869
- 3
- 27
- 55

- 89
- 7
This is enough
- (void)viewDidLoad {
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = NO;

- 3,465
- 1
- 31
- 24
This fixes the issue on both cases when:
- Showing Status Bar
Showing Status Bar + Navigation Bar
override func viewDidLayoutSubviews() { NSLog("ORIGIN: \(self.view.frame.origin.y)") if self.view.frame.origin.y == 0 { if let rect = self.navigationController?.navigationBar.frame { let y = rect.size.height + rect.origin.y self.tableView.contentInset = UIEdgeInsetsMake(y, 0, 0, 0) } } else if self.view.frame.origin.y == 44 || self.view.frame.origin.y == 64 { self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0) } }

- 39
- 2
- 9
The other answers may work for you, but they didn't work for me. What worked for me was to manually set the y
property of the contentOffset
in viewDidLayoutSubviews
and viewWillAppear
:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// Set the offset to go below the status bar
collectionView.contentOffset.y = -UIApplication.shared.statusBarFrame.height
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Set the offset to go below the status bar
collectionView.contentOffset.y = -UIApplication.shared.statusBarFrame.height
}
In my case, my controller had a child collection view which would sometimes get the contentOffset
adjusted and other times not. The way I normalized it was to just manually adjust it every time. I wanted the content to be offset to below the status bar, so I used the status bar height as the value (negative because I want the content to be pushed down).

- 1,811
- 18
- 20