why does Ios ignores top bar and layout items below it? - ios

I am designing a screen using IB and in design time this is how the screen looks like:
I am using auto layout and there are no missing constraints. This is how it lookes like when I run it using the simulator:
Its a sit it has no idea there is a opaque top bar there and starts layouting the views directly from the top.
does anyone has any idea why this is happening?
Thanks

The size, status bar, orientation, top bar, bottom bar are only simulated at the attributes inspector , e.i. What u see, is NOT what u get, it's just simulate...
To make status bar/bottom bar/orientation etc. U must do it via code or .xib attributes inspector/size inspector.
For status bar, u can see this.
Hope it's help.

Add the following code to viewDidLoad in you view controller:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}

You can achieve this by implementing a new property called edgesForExtendedLayout in iOS7 SDK. Please add the following code to achieve this,
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
You need to add the above in your -(void)viewDidLoad method.
iOS 7 brings several changes to how you layout and customize the appearance of your UI. The changes in view-controller layout, tint color, and font affect all the UIKit objects in your app. In addition, enhancements to gesture recognizer APIs give you finer grained control over gesture interactions.
Using View Controllers
In iOS 7, view controllers use full-screen layout. At the same time, iOS 7 gives you more granular control over the way a view controller lays out its views. In particular, the concept of full-screen layout has been refined to let a view controller specify the layout of each edge of its view.
The wantsFullScreenLayout view controller property is deprecated in iOS 7. If you currently specify wantsFullScreenLayout = NO, the view controller may display its content at an unexpected screen location when it runs in iOS 7.
To adjust how a view controller lays out its views, UIViewController provides the following properties:
edgesForExtendedLayout
The edgesForExtendedLayout property uses the UIRectEdge type, which specifies each of a rectangle’s four edges, in addition to specifying none and all. Use edgesForExtendedLayout to specify which edges of a view should be extended, regardless of bar translucency. By default, the value of this property is UIRectEdgeAll.
extendedLayoutIncludesOpaqueBars
If your design uses opaque bars, refine edgesForExtendedLayout by also setting the extendedLayoutIncludesOpaqueBars property to NO. (The default value of extendedLayoutIncludesOpaqueBars is NO.)
automaticallyAdjustsScrollViewInsets
If you don’t want a scroll view’s content insets to be automatically adjusted, set automaticallyAdjustsScrollViewInsets to NO. (The default value of automaticallyAdjustsScrollViewInsets is YES.)
topLayoutGuide, bottomLayoutGuide
The topLayoutGuide and bottomLayoutGuide properties indicate the location of the top or bottom bar edges in a view controller’s view. If bars should overlap the top or bottom of a view, you can use Interface Builder to position the view relative to the bar by creating constraints to the bottom of topLayoutGuide or to the top of bottomLayoutGuide. (If no bars should overlap the view, the bottom of topLayoutGuide is the same as the top of the view and the top of bottomLayoutGuide is the same as the bottom of the view.) Both properties are lazily created when requested.

Related

How to reproduce this "offset behavior" programmatically?

Since iOS 7, Apple encourages developers to show content behind navigation bars and other translucent elements.
Let's say that I have a view controller embedded in a navigation view, adding to this view controller a map view and extending the edges of the map view to the bounds of the screen (so even behind the navigation bar) gives the expected effect : the navigation bar blurs the content of the map view.
But iOS also does something else : although the map itself is rendered behind the navigation bar, if a ui element the user must see or touch (for example the compass) is actually offseted so that it isn't hidden by the navigation bar ; a picture is worth a thousand words :
What I would like to know is what property of the map view I should use to make it behave like this programmatically ? (because if I manually add a translucent view on the top of my map, the compass will be hidden, so I would like to be able to do that) ? This question also applies for other kinds of views, such as table views, is it the same principle ?
Thank you.
For UIScrollView and its subclasses (UICollectionView, UITableView), setting the contentInset to something like, say, UIEdgeInsetsMake(64.0 /* TOP */, 0.0 /* LEFT */, 44.0 /* BOTTOM */, 0.0 /* RIGHT */); would be the way to go.
You can inspect the UIViewController's properties topLayoutGuide and bottomLayoutGuide to determine how much you have to inset.
For MKMapView, I've tried adding it programmatically and it appear that it adjusts the frame of the compass and the "Legal" label automatically. I would say that it takes topLayoutGuide and bottomLayoutGuide into account to layout the button and label.

What is the extend edge property in UIViewController for ?

I have read on the forums about this property, mostly its people setting this this property to false or unchecking it in the storyboard.
I have done this myself because when I have a UINavigation Controller embedded in a View, the top bar pushes my UITextView down so the text starts editing at the bottom.
Unchecking Extended Edges Under Top Bars in the StoryBoard in the UIViewController solves my problem but I don't understand what is going on.
Can someone give an explanation on what the purpose of this property is, I would like to know more about it.
By default, UITableViewController's views are automatically inset in iOS7 so that they don't start below the navigation bar/status bar. This is controller by the "Adjust scroll view insets" setting on the Attributes Inspector tab of the UITableViewController in Interface Builder, or by the setAutomaticallyAdjustsScrollViewInsets: method of UIViewController.
For a UIViewController's contents, if you don't want its view's contents to extend under the top/bottom bars, you can use the Extend Edges Under Top Bars/Under Bottom Bars settings in Interface Builder. This is accessible via the edgesForExtendedLayout property.
Reference: Why does UIViewController extend under UINavigationBar, while UITableViewController doesn't?
See the images below:
I set 44 height red topview and 44 height red footview of tableview.
UIRectEdgeTop: The top edge of the rectangle.
UIRectEdgeBottom: The bottom edge of the rectangle.
The edgesForExtendedLayout property, together with the extendedLayoutIncludesOpaqueBars property, determines whether or not view controllers' views underlap top and bottom bars (navigation bar, toolbar, etc.)

UISearchBar on UITableView strange offset issue

I have a UITableView which has a UISearchBar subview. This is all on the view of a UIViewController along with a few other subviews (labels, text fields and such).
The search bar and content offset of the table are acting quite strangely, but it seems dependent on the order in which these views are added to the main view in the xib. I created a sample project with just my table/search and a label in order to test, and the result is the same. When the table is added after the label, everything works fine:
Setup:
Correct and Expected Result:
However, if I simply change the order in which my 2 subviews sit on the main view (aka table added before the label) then weird things start happening.
Apparently bad setup:
Weird offset of Search Bar:
I'm not changing anything else whatsoever, so why does Xcode seem to care which order these subviews are added to the main view?? If I scroll up on the "bad" table setup, the search bar disappears immediately at its top edge, but the table's content will continue to scroll up until it reaches the top of the frame that was set in the xib. Scroll back down and the search bar doesn't reappear until the strange lowered location. This is in Xcode 5.1.1, not the new beta. The result is the same with or without Autolayout turned on.
Any idea why this is happening? Is this a bug, or am I missing something? (I didn't post any code because all I'm doing is setting the number of sections, rows, and setting the text on the cell. Not messing with content insets, offset, anything. I load the view from the app delegate as the root of a nav controller)
This happens because a UIViewController's property called automaticallyAdjustsScrollViewInsets
With iOS 7, UIViewControllers have a property called
automaticallyAdjustsScrollViewInsets, and it defaults to YES. If you
have a scroll view that is either the root view of your view
controller (such as with a UITableViewController) or the subview at
index 0, then that property will adjust both the contentInset and the
scrollIndicatorInsets. This will allow your scroll view to start its
content and scroll indicators below the navigation bar (if your view
controller is in a navigation controller).
From Big Nerd Ranch
If you are using storyboards, you can change it by selecting the view controller and in the attributes inspector deselect Adjust scroll view insets.
Here is its description from apple documentation:
Default value is YES, which allows the view controller to adjust its
scroll view insets in response to the screen areas consumed by the
status bar, navigation bar, and toolbar or tab bar. Set to NO if you
want to manage scroll view inset adjustments yourself, such as when
there is more than one scroll view in the view hierarchy.
I have same problem before about position of tableview and searchbar. i tried the following and it works for me.
If you do not write code for that and if it is only problem of xib or storyboard then try all outlet's autosizing and origin setting to fix its position and see the difference. it may be work for you.
Update : automaticallyAdjustsScrollViewInsets has been deprecated in ios 11 and a new field contentInsetAdjustmentBehavior has been introduced.
if #available(iOS 11.0, *) {
tableview.contentInsetAdjustmentBehavior = .never
} else {
automaticallyAdjustsScrollViewInsets = false
}
UITableView header can contains only one UIView, so if you need UISearchBar plus UILabel, you need to wrap they into UIView and add this view as UITableView header.

UITableView Current section floating not where it should

An image is worth a 1000 words, so here is a screen :
As you can see, the "A" section is the current section and there is space above it and I can't understand why.
FWIW : It's a UISearchResultsTableView (UITableView subclass) create by a UISearchDisplayController.
This problem appear I think after some changed in the interface builder but I can't find what exactly.
It look likes it the space is the same height as the navigationbar.
By default, UITableViewController's views are automatically inset in iOS 7 so that they don't start below the navigation bar/status bar.
This is controller by the Adjust scroll view insets setting on the Attributes Inspector tab of the UITableViewController in Interface Builder, or by the setAutomaticallyAdjustsScrollViewInsets: method of UIViewController.
For a UIViewController's contents, if you don't want its view's contents to extend under the top/bottom bars, you can use the Extend Edges Under Top Bars/Under Bottom Bars settings in Interface Builder. This is accessible via the edgesForExtendedLayout property.
Try:
self.edgesForExtendedLayout = UIRectEdgeNone;
self.automaticallyAdjustsScrollViewInsets = NO;

UINavigationController bar covers its uiviewcontroller's content

I have a UIViewController, MyViewController, with a UIToolbar at the top. Using interface builder the doc outline looks like this:
View
- subview1
- subview2
- UIToolbar
- Bar Button Item1
- Bar Button Item2
- Bar Button Item3
MyViewController is used throughout my app. Sometimes it's in a UINavigationcontroller, other times it's in a UIPopoverView.
When it appears in UINavigationController, the navigation bar covers up the UIToolbar and all other content near the top of View. In this screenshot you can see that the UIToolbar is completely covered up, and UIButton w/ an image of a green light bulb is partially covered.
According to the apple documentation
Any view that needs to be anchored to the top and just below the status bar (i.e. UIToolbar, UIButton, etc.) requires additional work for proper placement.
It proceeds to give a solution that simply uses constraints to move your VC's content down by x pixels, in my case the UIToolbar. This doesn't seem like a good solution because it assumes you always want the content moved down below the nav bar. In my case, I obviously don't since MyViewController is not always in a UINavigationController. When I use the constraint solution provided in these docs, the UIToolbar is oddly floating down x pixels unanchored from the top in all cases where MyViewController is not in a UINavigationController.
Am I missing something with how I am supposed to display a VC's content within a UINavigationController? Thanks so much.
In iOS7, UINavigationBar has translucent property and views of child VCs of UINavigationViewController are underneath UINavigationBar by default.
If you don't need this translucent effect, turn off this property by using the following code.
self.navigationController.navigationBar.translucent = NO
You can also use #ldindu's way as well.
If you are running on iOS 7.0 version then you need to set following property which is newly introduced in iOS 7.0 as follows
self.edgesForExtendedLayout = UIRectEdgeNone;
as by default edgesForExtendedLayout property is set to UIRectEdgeAll that means the view controllers use full-screen layout by default.
Identify whether you are using iOS 7.
#define IS_IOS7 [[[UIDevice currentDevice] systemVersion] hasPrefix:#"7"];
- (float)topPadding
{
return (IS_IOS7) ? 20.0f : 0.0f;
}
Use increment the Y axis of the frame by [self topPadding] to move it further down.
I hope your problem is solved.
If written in Swift, it's edgesForExtendedLayout = UIRectEdge()

Resources