44

当 iPhone X 横向使用时,您应该检查 safeAreaInsets 以在左侧和右侧制作适当大的排水沟。UITableView 具有新insetsContentViewsToSafeArea属性(默认为 true),可自动将单元格内容保存在安全区域中。

我很惊讶 UICollectionView 似乎没有类似的东西。我希望对于垂直滚动的集合视图,在横向时,左侧和右侧将插入到安全区域(相反,如果需要在纵向中插入水平滚动的集合视图)。

确保此行为的最简单方法似乎是添加到集合视图控制器中:

- (void)viewSafeAreaInsetsDidChange {
    [super viewSafeAreaInsetsDidChange];
    UIEdgeInsets contentInset = self.collectionView.contentInset;
    contentInset.left = self.view.safeAreaInsets.left;
    contentInset.right = self.view.safeAreaInsets.right;
    self.collectionView.contentInset = contentInset;
}

...假设 contentInset.left/right 通常为零。

(注意:是的,对于 UICollectionViewController,它必须是self.view.safeAreaInsets;在调用它时,奇怪的是,更改safeAreaInsets尚未传播到self.collectionView

我错过了什么吗?该样板文件很简单,但现在对于每个触及屏幕边缘的集合视图来说,它实际上都是必需的。苹果没有提供默认启用此功能的功能,这似乎真的很奇怪。

4

6 回答 6

72

有同样的问题。这对我有用:

override func viewDidLoad() {
    if #available(iOS 11.0, *) {
        collectionView?.contentInsetAdjustmentBehavior = .always
    }
}

枚举案例的文档说:.always

始终在内容调整中包含安全区域插图。

在手机旋转的情况下,此解决方案也可以正常工作。

于 2017-10-11T15:06:41.820 回答
42

虽然 Nathan 关于 UICollectionView 具有各种布局的多功能性是正确的,但我主要关心的是使用 UICollectionViewFlowLayout 的“默认”情况。

事实证明,iOS 11sectionInsetReferenceUICollectionViewFlowLayout. 它的官方文档目前缺少描述,但是标题将其描述为

部分插入的参考边界将被定义为相对于。默认为.fromContentInset.

注意:将始终至少尊重内容插图。例如,如果 sectionInsetReference 等于.fromSafeArea,但调整后的 content inset 大于安全区域和 section inset 的组合,则 section 内容将与 content inset 对齐。

可能的值为

@available(iOS 11.0, *)
public enum UICollectionViewFlowLayoutSectionInsetReference : Int {
    case fromContentInset
    case fromSafeArea
    case fromLayoutMargins
}

并将其设置为.fromSafeArea产生所需的结果,即最初处于纵向时:

初始纵向布局

然后当旋转到横向时,单元格被插入,使得它们完全在安全区域内:

iPhone X 横向集合视图布局

...但是,当前存在一个错误,并且当视图处于横向后旋转回纵向时,它继续充当左/右 safeAreaInsets 设置为横向值:

从横向旋转后的纵向布局

我已经就这个问题提交了一份雷达 ( rdar://34491993 )。

于 2017-09-18T16:29:05.497 回答
11

感谢楼上的帮助。对于我的 UICollectionViewController 子类,我在 viewDidLoad() (Swift 3) 中添加了以下内容:

if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
    if #available(iOS 11.0, *) {
        flowLayout.sectionInsetReference = .fromSafeArea
    }
}
于 2017-09-29T17:21:42.630 回答
1

请记住,上述解决方案不能解决您的集合单元格视图(以及受限于其单元格的前缘或后缘的子视图)对集合视图边界全宽且未设置为遵守安全区域布局指南的情况.

注意:@petrsyn 的答案使标题从侧面插入,这是大多数人可能不想要的,@Wes Campaigne 的答案对于全角单元格并不能真正正常工作,其中子视图附加到前导或尾随单元格的边缘。

必须将 Xib 和 Storyboard 文件设置为使用安全区域布局指南,然后使用自动布局来放置与安全区域相关的约束或在代码中执行类似操作,尤其是对于那些来自较旧项目的人来说。

于 2018-01-28T20:39:38.343 回答
0

UICollectionView旨在灵活用于各种布局。最常见的布局是具有多行和多列的网格,但可以使用UICollectionView.

UITableView,另一方面,是为全宽单元格设计的。

因此,对处理安全区域插入的内置支持是有意义UITableView的,因为表格视图布局将始终受到它的影响。因为UICollectionView使用自定义布局,所以在每个实现的基础上解决这些问题而不是试图提供一种万能的解决方案是有意义的。

于 2017-09-16T21:17:12.703 回答
0

如果您以编程方式添加集合视图作为主视图的子视图 - 那么您可以在您的viewDidLoad方法中执行此操作:

collectionView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(collectionView)

NSLayoutConstraint.activate([
        collectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
        collectionView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
        collectionView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
        collectionView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor)
])
于 2020-05-29T21:27:20.123 回答