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

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

在这里输入图像说明

我设法使用新的安全区域布局指南,并保持与iOS 9和iOS 10的向后兼容性:( 编辑:如在@NickEntin的评论中指出的那样,这个实现将假设存在一个状态栏,在iPhone X的景观上是真实的。导致到顶部(20分)很多的空间,但它会运行得很好。

例如,如果您希望视图在状态栏下方10点(和iPhone X上的传感器shell下方10点):

  1. 在您的XIB中,转到File Inspector并启用安全function,方法是检查Use Safe Area Layout Guides
  2. 从视图的顶部到主视图顶部创build一个约束,其中>= (大于或等于)约束,常量30 (30,因为我们需要距离状态栏10点的距离,高20点)和优先级High (750) 。
  3. 从视图顶部到安全区域顶部创build一个约束,其中= (等于)约束,常量10和优先级Low (250)。

底部的视图(以及安全区域的前/后或左/右)也可以做到这一点:

  1. 在您的XIB中,转到File Inspector并启用安全function,方法是检查Use Safe Area Layout Guides
  2. 从视图的底部到主视图的底部创build一个约束,使用>= (大于或等于)约束,常量10和优先级High (750)。
  3. 从视图的底部到安全区域底部创build一个约束,其中= (等于)约束,常量10和优先级Low (250)。

至less有一个向后兼容性的问题,我已经在Xcode 9 GM中推出了安全区域约束的安全区域约束。

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

如果导航栏是可见的,并且“禁止顶部栏”,那么推送的视图将仍然在导航栏下滑动以到达屏幕的顶部。 导航栏放置正确。

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

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

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

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

我提出这个雷达#34477706。

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

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

变通办法似乎是要么

(a)将你的xibs迁移到storyboard或者

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

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

假设你在xib中有一个你想要保持在安全区域内的视图(即在任何状态栏或导航栏下面)。

  1. 在您的视图和iOS安全区域之间的xib中添加约束条件。将顶部约束条件分配给750的优先级。

    添加顶部约束

  2. 在你的视图控制器中,添加一个属性:

     @property (nonatomic, strong) NSLayoutConstraint *topLayoutConstraint; 

    然后在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]; } } } 

    新的约束将只为iOS 9和iOS 10创build,默认优先级为1000,并覆盖xib中的约束。

  3. 如果您需要避免归位指示符,请重复底部约束。

Swift版本会相似。

如果你使用没有故事板的xibs,那么他们没有ios 10的布局指南。所以把xib移动到故事板,以便具有向后兼容性。

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

我在两个平台(iOS 11和后向iOS 10)上都testing了现有的项目,并且没有使用“SafeAreaLayout”。 这工作正常。

只要确保:

  • 如果你在AutoLayout中devise了你的项目/用户界面, 您的UIElement的约束遵循/相对于顶部和底部布局指南(而不是超级视图)。 所以通过SafeAreaLayout选项的单击(启用),将自动实现SafeArea布局适当的故事板中的所有Interface Builders文件。

  • 如果您在SafeAreaLayout中devise了您的项目/用户界面, 那么它会自动跟随后向iOS中的顶部和底部布局指南。

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

安全区域布局: 在这里输入图像说明

自动版式

在这里输入图像说明

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

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

在Objective-C中,在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]; } 

“安全区域布局指南”是向后兼容的。 那么,除非你在xib中使用它。 与故事板,似乎确定。

我通过从我的视图顶部的第一个对象访问“顶部布局约束”来解决我的问题。

 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *topLayoutConstraint; 

然后,我将常量值更改为该约束并刷新视图。 例如,如果您使用导航栏(44高度)加上状态栏(20高度):

 if (SYSTEM_VERSION_LESS_THAN(@"11.0")) { _topLayoutConstraint.constant = 64; [self.view layoutIfNeeded]; } 

使用定义如下的SYSTEM_VERSION_LESS_THAN:

 #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) 

在iOS 9上,我有WKWebView和安全区域的向后兼容性问题。由于某种原因,WKWebView只是忽略安全区域布局设置。