Explaining difference between automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout in iOS7
Starting in iOS7, the view controllers use full-screen layout by default. At the same time, you have more control over how it lays out its views, and that's done with those properties:
edgesForExtendedLayout
Basically, with this property you set which sides of your view can be extended to cover the whole screen. Imagine that you push a UIViewController
into a UINavigationController
. When the view of that view controller is laid out, it will start where the navigation bar ends, but this property will set which sides of the view (top, left, bottom, right) can be extended to fill the whole screen.
Let see it with an example:
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
Here you are not setting the value of edgesForExtendedLayout
, therefore the default value is taken (UIRectEdgeAll
), so the view extends its layout to fill the whole screen.
This is the result:
As you can see, the red background extends behind the navigation bar and the status bar.
Now, you are going to set that value to UIRectEdgeNone
, so you are telling the view controller to not extend the view to cover the screen:
UIViewController *viewController = [[UIViewController alloc] init];
viewController.view.backgroundColor = [UIColor redColor];
viewController.edgesForExtendedLayout = UIRectEdgeNone;
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
And the result:
automaticallyAdjustsScrollViewInsets
This property is used when your view is a UIScrollView
or similar, like a UITableView
. You want your table to start where the navigation bar ends, because you wont see the whole content if not, but at the same time you want your table to cover the whole screen when scrolling. In that case, setting edgesForExtendedLayout
to None won't work because your table will start scrolling where the navigation bar ends and it wont go behind it.
Here is where this property comes in handy, if you let the view controller automatically adjust the insets (setting this property to YES, also the default value) it will add insets to the top of the table, so the table will start where the navigation bar ends, but the scroll will cover the whole screen.
This is when is set to NO:
And YES (by default):
In both cases, the table scrolls behind the navigation bar, but in the second case (YES), it will start from below the navigation bar.
extendedLayoutIncludesOpaqueBars
This value is just an addition to the previous ones. By default, this parameter is set to NO. If the status bar is opaque, the views won't be extended to include the status bar, even if you extend your view to cover it (edgesForExtendedLayout
to UIRectEdgeAll
).
If you set the value to YES, this will allow the view to go underneath the status bar again.
If something is not clear, write a comment and I'll answer it.
How does iOS know what UIScrollView to use?
iOS grabs the first subview in your ViewController's view, the one at index 0, and if it's a subclass of UIScrollView
then applies the explained properties to it.
Of course, this means that UITableViewController
works by default (since the UITableView
is the first view).
What is edgesForExtendedLayout: for?
'edgesForExtendedLayout' is used to specify which edges of a view should be extended, regardless of bar translucency.
May be you are using this as a view controller which is not embedded in any other view controller or is a root view controller.
You can refer it in apple's official documnetation here.
compatibility with automaticallyAdjustsScrollViewInsets
I don't see any problem. iOS 6 SDK does not contain this property. You just should use following code:
if([self respondsToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets:)])
{
self.automaticallyAdjustsScrollViewInsets = NO;
}
TextViews not in correct position in ScrollView
In your viewDidLoad set viewController autoScollViewInsets to false:
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false
}
you want more detail about this check this answer:
Explaining difference between automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout in iOS7
iOS popViewControllerAnimated black bar appear
After reading the post Explaining difference between automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout in iOS7,I have figured out a solution.
Set extendedLayoutIncludesOpaqueBars
to true.
func viewDidLoad() {
extendedLayoutIncludesOpaqueBars = true // property introduced in iOS7,default value is false
}
first cell UItableViewController issue Swift
If your navigationVC has a translucent navigation bar and you want to tableview to be visible under the navigation bar when you scroll, then in your Storyboard, check the "Under Top Bars" which means you want the VC to scroll underneath the navigation bar and also check "Adjust Scroll View Inset" so that the scroll start below the navigation bar.
More detailed explanation can be found here:
Explaining difference between automaticallyAdjustsScrollViewInsets, extendedLayoutIncludesOpaqueBars, edgesForExtendedLayout in iOS7
Note that this only works if your tableViewController is the rootView of your navigationVC.
In the special case of navVC -> PageVC ->TableVC add this to your tableview viewWillAppear
self.tableView.contentInset = UIEdgeInsetsMake(CGRectGetMaxY(self.navigationController.navigationBar.frame), 0,0,0);
if(self.tableView.contentOffset.y == 0 ){
self.tableView.contentOffset = CGPointMake(0, -CGRectGetMaxY(self.navigationController.navigationBar.frame));
}
UIScrollView behaves differently when embedded in a navigation controller
As per the above two edits, the problem was solved by removing this line...
self.view.setTranslatesAutoresizingMaskIntoConstraints(false)
...and adding this one:
self.automaticallyAdjustsScrollViewInsets = false
IOS7 : UIScrollView offset in UINavigationController
OK so i found the solution, I have set in my controller the property:
self.automaticallyAdjustsScrollViewInsets = false
I don't really understand the true benefit of this property though, (or why the default value is true)
The only documentation i found was there:
- https://web.archive.org/web/20160405135605/https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/AppearanceCustomization.html
- https://developer.apple.com/documentation/uikit/uiviewcontroller/1621372-automaticallyadjustsscrollviewin
Update
In iOS 11 automaticallyAdjustsScrollViewInsets
is deprecated
You should now use:
self.tableView.contentInsetAdjustmentBehavior = .never
I also encourage you to check this question and its answer to get a better understanding of those properties
Related Topics
What Does Enable_Bitcode Do in Xcode 7
Find Out If Character in String Is Emoji
Iphone Keyboard Covers Uitextfield
Protocol Can Only Be Used as a Generic Constraint Because It Has Self or Associatedtype Requirements
Design For Facebook Authentication in an iOS App That Also Accesses a Secured Web Service
Why Isn't Projectname-Prefix.Pch Created Automatically in Xcode 6
"Warning: Iphone Apps Should Include an Armv6 Architecture" Even With Build Config Set
How to Inspect the View Hierarchy in Ios
How to Create a Custom Uiactivity in Ios
Left Align Cells in Uicollectionview
Openurl Not Work in Action Extension
Push Notification Issue With iOS 10
Iphone Hide Navigation Bar Only on First Page
Xcode 4.2 Debug Doesn't Symbolicate Stack Call