如何垂直居中 UICollectionView 内容

Posted

技术标签:

【中文标题】如何垂直居中 UICollectionView 内容【英文标题】:How to vertically center UICollectionView content 【发布时间】:2015-11-27 16:37:52 【问题描述】:

我正在尝试使 UICollectionView 的内容动态居中,但是现有的解决方案都没有考虑到每行可能有多个单元格这一事实。

我已经尝试了这个center custom title in UINavigationBar? 以及这里的两种解决方案:UICollectionView vertically Centred,但无济于事。

我很惊讶 ios 在默认情况下没有提供这样做的方法,更重要的是无法获取当前显示的行数(这也可以解决我的问题)。此外,我无法获得内容的大小(而不仅仅是框架的大小),这也有助于我达到预期的效果。

我有这个:

 --------
|X X X X |
|X X X X |
|        |
|        |
 --------

但我想要这个:

 --------
|        |
|X X X X |
|X X X X |
|        |
 --------

任何帮助将不胜感激,

非常感谢。

【问题讨论】:

我不明白你的问题。如何“获取”行数是什么意思?你告诉集合视图项目的数量、它们的大小等...... @Darko:为了使一组单元格居中,我需要能够知道集合视图正在显示多少行(这与项目数不同,因为可以显示多个项目一行,取决于屏幕大小)。一旦我有了单元格的数量,我就可以将顶部插图设置为(collectionview 框架高度 - 单元格占据的总高度)/2。我已经为我的问题添加了视觉表示。 关于你的视觉表现——如果你想要第 2 版,你为什么要把集合视图做得这么大?只需将其缩小并使用自动布局将其置于屏幕中心即可。除此之外(正如 jorf 已经回答的那样),您可以设置部分插图。但在我看来,插图只有在您想在运行时更改它时才有用。如果布局是固定的,只需缩小集合视图。 @Darko 因为根据屏幕尺寸,我得到了非常不同的布局。在 12 个项目的 iphone 6s 上,我得到两行 6 个单元格。在 iphone 4s 上,我得到 6 行,每行 2 件。不确定我是否可以通过自动布局来解释这一点。 啊,好的,现在我明白你的问题了。根据屏幕尺寸,您需要另一个插图以使其看起来居中。然后你必须手动计算它,但它不应该那么难。您知道可用空间、项目数和单元格大小。只需从顶部计算部分插图。 【参考方案1】:

不知道为什么你不能得到内容的大小——UICollectionView 是一个UIScrollView 子类,因此可以访问contentSize 属性。如果您只需要将单元格居中以防它们在不滚动的情况下全部可见,您可以简单地执行以下操作:

collectionView.contentInset.top = max((collectionView.frame.height - collectionView.contentSize.height) / 2, 0)

这也适用于单元格数量增加以至于并非所有单元格都在屏幕上可见并且您开始使用垂直滚动的情况下 - 顶部插图将设置为0

【讨论】:

【参考方案2】:

现在我明白你的问题了。根据屏幕尺寸,您需要另一个插图以使其看起来居中。然后你必须手动计算它,但它不应该那么难。您知道可用空间、项目数和单元格大小。只需从顶部计算部分插图。

【讨论】:

你能在这里写代码吗?我明白你的意思但是我不知道哪些代码适合这个【参考方案3】:

这是一个旧线程,但我认为缺少最明显的解决方案。

我会简单地将 UICollectionView 放在一个完整的视图容器中,并将集合视图的中心与自动布局对齐。

UICollectionView 应该采用适合单元格的最佳尺寸,然后保持居中。

【讨论】:

【参考方案4】:

UICollectionView 有一个 visibleCells 属性,它返回一个数组。您可以使用NSArray 上的count 属性来获取可见单元格的数量。

您应该能够在您的委托实现中实现 - collectionView:layout:insetForSectionAtIndex: 以将顶部插图设置为将导致您正在拍摄的居中的东西。

如果需要,您还可以继承 UICollectionViewFlowLayout 并实现自己的布局逻辑。

【讨论】:

请参阅我对 Darko 的第二条评论,了解为什么这不是一个可行的解决方案。这假设无论屏幕大小如何,每一行都有相同数量的单元格。尽管所有单元格都是可见的,但它们不会显示在一组固定的行上。 这个问题对我来说仍然存在,你能帮帮我吗?这是我的问题链接***.com/questions/49727912/…【参考方案5】:

如果你有一个 tabBar 就这样做

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets 

    let navBarHeight       = self.navigationController?.navigationBar.frame.height
    let collectionViewHeight = (self.collectionView?.frame.height)! - navBarHeight!
    let itemsHeight        = self.collectionView?.contentSize.height

    let topInset = ( collectionViewHeight - itemsHeight! ) / 4

    return UIEdgeInsetsMake(topInset ,0, 0 , 0)

如果不忽略 tabBar 减法,剩下的就剩下...

【讨论】:

【参考方案6】:

viewDidLoad

中添加这个
let viewHeight: CGFloat = view.center.y
let contentHeight: CGFloat = collectionView.contentSize.height
let marginHeight: CGFloat = (viewHeight - contentHeight) / 2.0
self.collectionView.contentInset = UIEdgeInsets(top: marginHeight, left: 0, bottom:  0, right: 0)

【讨论】:

以上是关于如何垂直居中 UICollectionView 内容的主要内容,如果未能解决你的问题,请参考以下文章

如何在 div 块内居中文本(水平和垂直)?

如何在列内垂直和水平居中文本? [复制]

如何在flex元素内垂直居中文本[重复]

如何在响应式页面上的 div 内垂直和水平居中两个图像

如何在垂直 Gtk.Box 内水平居中 Gtk.Grid?

如何在固定高度的div内垂直居中动态高度的图像?