iOS 11安全区域布局指导向后兼容性

Ted*_*Ted 62 xcode compatibility ios swift safearealayoutguide

启用安全区域布局指南是否与iOS 11以下兼容?

在此输入图像描述

thi*_*ine 53

我设法使用新的安全区布局指南并保持与iOS 9和iOS 10的向后兼容性:( 编辑:正如@NickEntin的评论所指出的,这个实现将假设存在一个状态栏,它不会在iPhone X的横向上是真实的.导致到顶部的很多空间(20点).然而它将完美地运行.

例如,如果您希望视图位于状态栏下方10个点(并且iPhone X上传感器外壳下方10个点):

  1. 在您的XIB中,File Inspector通过检查转到并启用保险箱Use Safe Area Layout Guides.
  2. 从视图的顶部到主视图的顶部创建一个约束,具有>=(大于或等于)约束,常量30(30因为我们希望10个点间距到状态栏,即20点高)和优先级High(750).
  3. 从视图的顶部到安全区域的顶部创建约束,具有=(相等)约束,常量10和优先级Low(250).

对于底部的视图(以及对于安全区域的前导/尾随或左/右),可以执行相同的操作:

  1. 在您的XIB中,File Inspector通过检查转到并启用保险箱Use Safe Area Layout Guides.
  2. 从视图的底部到主视图的底部创建约束,具有>=(大于或等于)约束,常量10和优先级High(750).
  3. 从视图的底部到安全区域的底部创建一个约束,具有=(相等)约束,常量10和优先级Low(250).

  • 安全布局是 xcode 9 中的主要视图。我们将如何应用第 2 点?在 2 和 3 中,我们不会创建具有相同视图的约束吗? (2认同)

小智 45

只有在使用故事板时,iOS 9和iOS 10的安全区域的向后兼容性才有效.如果您使用的是xib,则没有可以回退的布局指南. https://forums.developer.apple.com/thread/87329

解决方法似乎也是

(a)将你的xib迁移到故事板,或

(b)以编程方式增加一些额外的限制.

如果(a)不是一个真正的选择,手动方法将是这样的:

假设您的xib中有一个视图,您希望保留在安全区域内(即在任何状态栏或导航栏下方).

  1. 在视图和iOS 11安全区域之间的xib中添加约束.将顶部约束指定为优先级750.

    添加顶部约束

  2. 在视图控制器中,添加属性:

    @property (nonatomic, strong) NSLayoutConstraint *topLayoutConstraint;
    
    Run Code Online (Sandbox Code Playgroud)

    然后在viewDidLayoutSubviews中:

    - (void)viewDidLayoutSubviews {
        [super viewDidLayoutSubviews];
    
        if (@available(iOS 11, *)) {
            // safe area constraints already set
        }
        else {
            if (!self.topLayoutConstraint) {
                self.topLayoutConstraint = [self.<yourview>.topAnchor constraintEqualToAnchor:self.topLayoutGuide.bottomAnchor];
                [self.topLayoutConstraint setActive:YES];
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    新约束仅为iOS 9和iOS 10创建,默认优先级为1000,并覆盖xib中的约束.

  3. 如果您需要避开主页指示符,请重复底部约束.

Swift 4版本:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if #available(iOS 11, *) {
        // safe area constraints already set
    } else {
        if topLayoutConstraint == nil {
            topLayoutConstraint = <yourview>.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor)
            topLayoutConstraint?.isActive = true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


cla*_*rus 18

对于我在Xcode 9 GM中观察到的iOS 11的安全区域限制,肯定至少存在一个向后兼容性问题 - 推出了具有安全区域限制的视图控制器.

如果隐藏了导航栏并且您推送了一个安全区域顶部约束视图,则推送的视图将与iOS 9和10上的状态栏重叠.

如果导航栏可见,并且"顶部栏"处于禁用状态,则推送的视图仍将在导航栏下方向上滑动以到达屏幕顶部.导航栏正确放置.

在iOS 11上,两种情况下的布局都是正确的.

这是一个简单的例子:http://www.filedropper.com/foobar

这是一个隐藏导航栏的视频(左侧为iOS 10.3,右侧为iOS 11):https://vimeo.com/234174841/1e27a96a87

这是导航栏可见的版本(在笔尖中启用):https: //vimeo.com/234316256/f022132d57

我把它作为雷达#34477706提交.

感谢@Sander指出导航栏可见的情况.

  • 因此,就解决方法而言,我想到了一些事情,其中​​没有一个是好的,但是...... 1)你可以在iOS 11之前使用单独的笔尖/故事板.根据应用程序的复杂程度,可能是一个真正的痛苦或超级简单.或者2)如果导航栏被隐藏,则具有> = 20的顶部约束以监视具有状态栏但没有导航(1000优先级)的视图以及安全区域(优先级为750)的视图.这有效,不应该导致问题.对于导航栏可见情况,这更棘手.我仍在努力寻找一个好的解决方案. (3认同)
  • 是的.这太荒谬了.我不得不使用许多变通办法让iOS 9和10中的游戏发挥得很好.这是Apple的说法"是的,很抱歉听到.....但我们不关心ios10或9".:) (3认同)
  • 如果未隐藏导航栏,则错误是相同的.在iOS 9和10版本上,推送视图位于导航栏下方.或者这种情况应该以不同的方式处理? (2认同)

Kru*_*nal 7

是的,您的项目/应用程序将在iOS 11之前的iOS版本中运行,没有任何问题.在11之前的iOS版本中,它将安全区域布局替换为正常的AutoLayout,并遵循"顶部和底部规则"布局指南.

我在两个平台(iOS 11和后向iOS 10)上使用和不使用"SafeAreaLayout"测试了我现有的项目.它工作正常.

请确保:

  • 如果您在AutoLayout中设计了项目/用户界面; 您的UIElement的约束遵循/相对于顶部和底部布局指南(而不是超级视图).因此,只需在SafeAreaLayout选项上单击(启用),就会自动为故事板中的所有Interface Builders文件实现SafeArea布局.

  • 如果您在SafeAreaLayout中设计了项目/用户界面; 然后它会自动跟随iOS中的Top和Bottom布局指南.

以下是带有结果的示例快照,通过启用或禁用安全区域布局,不会影响现有设计.

安全区域布局: 在此输入图像描述

自动版式

在此输入图像描述

简而言之,您的问题的答案是:"启用与11之前的iOS兼容的安全区域布局指南"

您可以在项目/应用程序中实现安全区域布局,通过将安全区域布局转换为顶部,它可以在以前的iOS版本中正常工作和底部布局.

  • 我发现它在故事板中很好地转换它,但在xib文件中失败...它只是忽略了iOS 10中的状态栏大小 (14认同)
  • 在我的测试中,它适用于iOS 11,在iOS 10上失败.似乎这样的东西仍然有一些错误.我稍后会发一个完整的问题,谢谢你的帮助. (3认同)

小智 7

如果你使用没有storyboard的xibs,那么他们在ios 10上没有布局指南.所以将xib移动到storyboard以具有向后兼容性.


Dmi*_* A. 6

当我在 UIView 中有一个导航栏时,我在 Objective-C 中使用了它,并且在 iOS 10 中取得了不错的结果。如果您在 xib 中使用 SafeArea,那么您可以添加viewDidLoad

if (@available(iOS 11.0, *)) {}
else {
    self.edgesForExtendedLayout = UIRectEdgeNone;
}
Run Code Online (Sandbox Code Playgroud)


Mad*_*uus 6

斯威夫特 5

我只是这样做。它很简单,非常接近真实的东西(只是添加了一个“r”)。

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

像这样使用:

button.topAnchor.constraint(equalTo: view.saferAreaLayoutGuide.topAnchor, constant: 16)
Run Code Online (Sandbox Code Playgroud)