iOS 11 safe area layout guide backwards compatibility

前端 未结 16 1105
忘了有多久
忘了有多久 2020-12-02 05:42

Is enabling Safe Area Layout Guides compatible to iOS below 11?

相关标签:
16条回答
  • 2020-12-02 05:56

    Swift 5

    I just do this. It is simple and very close to the real thing (just added an 'r').

    extension UIView {
        var saferAreaLayoutGuide: UILayoutGuide {
            get {
                if #available(iOS 11.0, *) {
                    return self.safeAreaLayoutGuide
                } else {
                    return self.layoutMarginsGuide
                }
            }
        }
    }
    

    Use like this:

    button.topAnchor.constraint(equalTo: view.saferAreaLayoutGuide.topAnchor, constant: 16)
    
    0 讨论(0)
  • 2020-12-02 05:58

    There's definitely at least one backwards compatibility issue with iOS 11's safe area constraints that I've observed in the Xcode 9 GM--pushed view controllers with safe area constraints.

    If your navigation bar is hidden and you push a safe area top-constrained view, the pushed view will overlap the status bar on iOS 9 & 10.

    If the navigation bar is visible, and "under top bars" disabled, the pushed view will still slide up under the nav bar to get to the top of the screen. The navigation bar is placed correctly.

    On iOS 11, the layout will be correct in both cases.

    Here's a simple example: http://www.filedropper.com/foobar

    And here's a video of it w/nav bar hidden (iOS 10.3 on left, iOS 11 on right): https://vimeo.com/234174841/1e27a96a87

    Here's a version where the nav bar is visible (enabled in the nib): https://vimeo.com/234316256/f022132d57

    I filed this as Radar #34477706.

    Thanks to @Sander for pointing out the nav bar visible case.

    0 讨论(0)
  • 2020-12-02 06:02

    If you use xibs without storyboard then they don't have layout guides on ios 10. So move xib to storyboard to have backward compatibility.

    0 讨论(0)
  • 2020-12-02 06:05

    Yes, your project/app will work in iOS versions prior to iOS 11 without any issue. In iOS versions prior to 11, it replaces/considers Safe Area Layout into normal AutoLayout and follows Rules of Top and Bottom layout guide.

    I tested my existing project with and without 'SafeAreaLayout' on both platforms (iOS 11 and backward iOS 10). It's working fine.

    Just make sure:

    • If you have designed your project/User Interface in AutoLayout; constraints of your UIElement follows/relative to Top and Bottom layout guide (not to superview). So by a single click (enable) on SafeAreaLayout option, will automatically implement SafeArea layout properly for all Interface Builders files in your storyboard.

    • If you have designed your project/User Interface in SafeAreaLayout; then it will automatically follow Top and Bottom layout guide in backward iOS.

    Here is sample snapshot with result, By enabling or disabling Safe Area layout, won't effect on existing design.

    Safe Area Layout:

    AutoLayout

    In short, an answer to your question is: "Enabling Safe Area Layout Guides compatible to iOS prior to 11"

    You can implement Safe Area Layout in your project/app and it will work fine with previous iOS versions by converting Safe Area Layout into Top and Bottom Layout.

    0 讨论(0)
  • 2020-12-02 06:06

    Simple Swift 4 Solution:

    First set to top constraint priority to the safe area to 750, then:

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        if #available(iOS 11, *) {
            // Safe area constraints already set.
        } else {
            NSLayoutConstraint.activate([
                self.yourView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor)
            ])
        }
    }
    
    0 讨论(0)
  • 2020-12-02 06:07

    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];
    
    }
    
    0 讨论(0)
提交回复
热议问题