Is enabling Safe Area Layout Guides compatible to iOS below 11?
I was using this in Objective-C when I had a Navigation Bar in my UIView and had good results for iOS 10.
In case you use SafeArea in your xib then you may add in your viewDidLoad
:
if (@available(iOS 11.0, *)) {}
else {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
When you have a generic ViewController that all your ViewControllers extend, another solution would be to put the items that should be adjusted in an IBOutletCollection and adjust them programmatically in that GenericViewController. Here's my code :
@IBOutlet var adjustTopSpaceViews: [UIView]?
override func viewDidLoad() {
super.viewDidLoad()
adjustViews()
....
}
func adjustViews() {
guard let views = adjustTopSpaceViews,
ProcessInfo.processInfo.operatingSystemVersion.majorVersion < 11 else {
return
}
let statusBarHeight = UIApplication.shared.statusBarFrame.height
for subview in views {
subview.superview?.constraints.filter({ (constraint) -> Bool in
return constraint.firstAttribute == .top
&& constraint.secondAttribute == .top
&& (constraint.firstItem as? UIView == subview || constraint.secondItem as? UIView == subview)
}).forEach({ (constraint) in
constraint.constant += (constraint.firstItem as? UIView == subview) ? statusBarHeight : -statusBarHeight
})
}
}
"safe area layout guide" is backward compatible. Well, unless you use it in xib. With storyboard it seems ok.
I solved my problem by accessing the "Top layout constraint" from the first object at the top of my view.
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *topLayoutConstraint;
then, I changed the Constant value to that constraint and refresh the view. For example, if you use a navigation bar (44 height) plus the status bar (20 height) :
if (SYSTEM_VERSION_LESS_THAN(@"11.0")) {
_topLayoutConstraint.constant = 64;
[self.view layoutIfNeeded];
}
With SYSTEM_VERSION_LESS_THAN which is defined like that :
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
Here is my iOS 9 to iOS 11+ solution wrapper in swift 4+
let safeAreaTopAnchor:NSLayoutYAxisAnchor?
if #available(iOS 11.0, *) {
safeAreaTopAnchor = contentView.safeAreaLayoutGuide.topAnchor
} else {
// Fallback on earlier versions
var parentViewController: UIViewController? {
var parentVCResponder: UIResponder? = self
while parentVCResponder != nil {
parentVCResponder = parentVCResponder!.next
if let viewController = parentVCResponder as? UIViewController {
return viewController
}
}
return nil
}
safeAreaTopAnchor = parentViewController?.topLayoutGuide.bottomAnchor
}