My application already in app store, yesterday i have updated my Xcode version to 9 and works fine except iPhone x. UI got collapsed.
1.Here I have Created Two UIView(both are fixed height) named as Header and Tab bar and I have hidden my NavigationBar entire app.
2.Added extension to UIViewController for making Header and Tab bar
func addHeaderTab(currentViewController:UIViewController,content:String, isMenu:Bool){
let noView = TopHeaderView()
noView.tag = 12345
noView.isMenu = isMenu
noView.translatesAutoresizingMaskIntoConstraints = false
currentViewController.view .addSubview(noView)
if isMenu{
noView.menuBtn .setImage(UIImage(named: "Small"), for: .normal)
noView.logoImg.isHidden = false
}else{
noView.menuBtn .setImage(UIImage(named: "arrow_small"), for: .normal)
noView.logoImg.isHidden = true
}
noView.titleLbl.text = content
noView.delegate = (currentViewController as! menuOpen)
NSLayoutConstraint(item: noView, attribute: .leading, relatedBy: .equal, toItem: currentViewController.view, attribute: .leading, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: noView, attribute: .trailing, relatedBy: .equal, toItem: currentViewController.view, attribute: .trailing, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: noView, attribute: .top, relatedBy: .equal, toItem: currentViewController.view, attribute: .top, multiplier: 1.0, constant: 0.0).isActive = true
NSLayoutConstraint(item: noView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1.0, constant: 64).isActive = true
}
and calling this every Viewcontroller like below :
self.addHeaderTab(currentViewController: self, content:"நிகழ்ச்சி நிரல்" , isMenu: true)
Like that Tab bar also i have done but all the device working expect iPhone x.
See My screen shot :
i have studied about https://developer.apple.com/ios/human-interface-guidelines/overview/iphone-x/
but am not clear with their document.
Help would be appreciated, Thanks in advance.
With iOS11 (and the appearance of iPhoneX) Apple introduced the Safe Area Layout Guide to adapt your views to the iPhoneX.
The Safe Area is the area of the screen that is not overlapped by the notch or the home indicator.
To avoid the issue you are experiencing you have to change your noView's top constraint for iOS11:
if #available(iOS 11, *) {
let guide = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
noView.topAnchor.constraint(equalTo: guide.topAnchor)
])
} else {
NSLayoutConstraint.activate([
noView.topAnchor.constraint(equalTo: currentViewController.topLayoutGuide.bottomAnchor)
])
}
NSLayoutConstraint.activate([
noView.leadingAnchor.constraint(equalTo: currentViewController.view.leadingAnchor),
noView.trailingAnchor.constraint(equalTo: currentViewController.view.trailingAnchor),
noView.heightAnchor.constraint(equalToConstant: 65)
])
Unfortunately that is not all. Because now your noView
moves down on iPhone X, but the status bar does not have a red background anymore. You have add a red background color behind the status bar:
You could make things a lot easier by using a UINavigationController (with a red navigation bar):
With this approach you don't have to set any constraints! The systems does all the adjustments for you automatically.
In Objective-C for top and bottom margin when on iPhone-X
if (@available(iOS 11, *)) {
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:self.childView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.parentView.safeAreaLayoutGuide
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0];
NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:self.childView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.parentView.safeAreaLayoutGuide
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0];
} else {
NSLayoutConstraint *bottomConstraint = [NSLayoutConstraint constraintWithItem:self.childView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:self.parentView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:0];
NSLayoutConstraint *topConstraint = [NSLayoutConstraint constraintWithItem:self.childView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.parentView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:0];
}
If you don't want to use a UINavigationController
but you want to have a navigation bar, you can do this way (using a UIImageView
):
https://medium.com/@kahseng.lee123/creating-custom-navigation-bar-tab-bar-for-iphone-x-f03b1e1827d3
Or you can create a view and set its top constraint to the top of the superview and its bottom contraint to the top of the navigation bar. Don't forget to make it red. :-)
Set height constrain of headerView according to the device.
if iPhoneX {
NSLayoutConstraint(item: noView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1.0, constant: 64+24).isActive = true
} else {
NSLayoutConstraint(item: noView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1.0, constant: 64).isActive = true
}
And set all the subView's(of headerView) constrain respective to bottom of superview(headerView).
Additional note on why we have added 24 pixel for iphoneX:
// portrait orientation - status bar is shown
additionalSafeAreaInsets.top = 24.0
来源:https://stackoverflow.com/questions/46344381/ios-11-layout-guidance-about-safe-area-for-iphone-x