热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

UICollectionView在iPhoneX上的风景。-UICollectionViewinlandscapeoniPhoneX

WheniPhoneXisusedlandscape,youresupposedtochecksafeAreaInsetstomakesuitablylargegutt

When iPhone X is used landscape, you're supposed to check safeAreaInsets to make suitably large gutters on the left and right. UITableView has the new insetsContentViewsToSafeArea property (default true) to automatically keep cell contents in the safe area.

当iPhone X被使用的时候,你应该检查safeAreaInsets,在左边和右边做出适当的大排水口。UITableView具有新的insetsContentViewsToSafeArea属性(默认为true),可以在安全区域自动保存单元格内容。

I'm surprised that UICollectionView seems to not have anything similar. I'd expect that for a vertically-scrolling collection view, the left and right sides would be inset to the safe area when in landscape (and conversely, a horizontally-scrolling collection view would be inset if needed in portrait).

我很惊讶UICollectionView似乎没有类似的东西。我希望在垂直滚动的集合视图中,在风景中,左边和右边会被插入到安全区域(反之,如果需要的话,一个水平滚动的集合视图会被插入)。

The simplest way to ensure this behaviour seems to be to add to the collection view controller:

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

- (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;
}

... assuming contentInset.left/right are normally zero.

…假设contentInset。左/右通常是零。

(NOTE: yes, for a UICollectionViewController, that needs to be self.view.safeAreaInsets; at the time this is called, the change to safeAreaInsets has oddly not yet propagated to self.collectionView)

(注:是的,对于UICollectionViewController,需要self。view. safeareainsets;在这个调用的时候,对safeAreaInsets的更改还没有传播到self。collectionview)

Am I missing something? That boilerplate is simple enough, but it's effectively necessary now for every collection view that touches a screen edge. It seems really odd that Apple didn't provide something to enable this by default.

我遗漏了什么东西?这个样板文件很简单,但是现在对于每一个触摸屏幕边缘的集合视图来说都是必要的。苹果在默认情况下没有提供支持这一功能,这似乎真的很奇怪。

5 个解决方案

#1


35  

Having the same issue. This worked for me:

有同样的问题。这工作对我来说:

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

The documentation for the .always enum case says:

关于.always enum案例的文档说明:

Always include the safe area insets in the content adjustment.

在内容调整中始终包括安全区域内设置。

This solution works correctly also in the case the phone is rotated.

这个解决方案在手机旋转的情况下也能正常工作。

#2


31  

While Nathan is correct about the versatility of UICollectionView with various layouts, I was mainly concerned about the "default" case where one is using UICollectionViewFlowLayout.

虽然内森对UICollectionView的多种布局的多样性是正确的,但我主要关心的是使用UICollectionViewFlowLayout的“默认”情况。

Turns out, iOS 11 has added a sectionInsetReference property to UICollectionViewFlowLayout. The official documentation on it currently lacks a description, however the headers describe it as

事实证明,ios11在UICollectionViewFlowLayout中添加了sectionInsetReference属性。官方文件目前没有描述,但是标题描述的是。

The reference boundary that the section insets will be defined as relative to. Defaults to .fromContentInset.

section insets的引用边界将被定义为相对的。默认为.fromContentInset。

NOTE: Content inset will always be respected at a minimum. For example, if the sectionInsetReference equals .fromSafeArea, but the adjusted content inset is greater that the combination of the safe area and section insets, then section content will be aligned with the content inset instead.

注:内容嵌入将永远被尊重。例如,如果sectionInsetReference等于。fromsafearea,但是调整后的内容inset更大,即安全区域和section insets的组合,那么section内容将与内容inset对齐。

The possible values are

可能的值是

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

and setting it to .fromSafeArea produces the desired results, i.e., when initially in portrait orientation:

并将其设置为。fromsafearea产生所需的结果,即。,最初在肖像方向:

initial portrait layout

then when rotating to landscape, the cells are inset such that they are entirely within the safe area:

然后当旋转到景观时,这些细胞被镶嵌在一起,它们完全在安全区域内:

iPhone X landscape collection view layout

... HOWEVER, there's currently a bug, and when rotating back to portrait after the view has been in landscape, it continues to act as if the left/right safeAreaInsets are set to the landscape values:

…然而,目前有一个bug,当视图在风景中出现后,当它旋转回到肖像时,它会继续表现为左/右的safeAreaInsets设置为景观值:

portrait layout following rotation from landscape

I've filed a radar (rdar://34491993) regarding this issue.

关于这个问题,我已经提交了雷达(rdar://34491993)。

#3


4  

Thanks to above for help. For my UICollectionViewController subClass, I added the following to viewDidLoad() (Swift 3):

感谢上面的帮助。对于我的UICollectionViewController子类,我添加了以下到viewDidLoad() (Swift 3):

if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
    if #available(iOS 11.0, *) {
        flowLayout.sectiOnInsetReference= .fromSafeArea
    }
}

#4


0  

UICollectionView is intended to be flexible for a wide variety of layouts. The most common layouts are grids with multiple rows and columns, but it's possible to create non-grid layouts with UICollectionView.

UICollectionView旨在为各种各样的布局提供灵活性。最常见的布局是具有多行和列的网格,但可以用UICollectionView创建非网格布局。

UITableView, on the other hand, is designed for full-width cells.

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

Therefore, it makes sense that UITableView would have built-in support for dealing with safe area insets, since table view layouts will always be affected by it. Because UICollectionView uses custom layouts, it makes sense to solve these issues on a per-implementation basis instead of trying to provide a one-size-fits-all solution.

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

#5


0  

Bare in mind the above solutions do not solve the case where your collection cell views (and subviews that are constrained to its cell's leading or trailing edges) are full-width to the collection view bounds and aren't set to obey Safe Area Layout Guides.

请注意,上面的解决方案并不能解决您的集合单元视图(以及被限制在其单元的前缘或后边缘的子视图)是全宽度到集合视图边界的情况,并且不会被设置为遵守安全区域布局指南。

Note: The answer by @petrsyn makes the header inset from the sides, which most people might not want and the answer by @Wes Campaigne doesn't really work correctly for full-width cells, where a subview is attached to the leading or trailing edges of the cell.

注意:@petrsyn的答案会使标题从两边开始,大多数人可能不愿意,而@Wes活动的答案在全宽度的单元格中并没有正确的工作,在这里,子视图连接到单元格的前缘或后缘。

It's imperative, especially for those coming from older projects, to set your Xib and Storyboard files to Use Safe Area Layout Guides and then use auto layout to place constraints respective to the the safe areas or do similar in code.

这是非常必要的,特别是对于那些来自旧项目的人来说,将Xib和故事板文件设置为使用安全区域布局指南,然后使用自动布局将约束分别放置到安全区域或在代码中执行类似的操作。


推荐阅读
author-avatar
陈政德169384
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有