UICollectionView 双向滚动

Posted

技术标签:

【中文标题】UICollectionView 双向滚动【英文标题】:UICollectionView scrolling in both directions 【发布时间】:2012-11-01 14:55:37 【问题描述】:

我制作了一个带有垂直滚动条的UICollectionView

单元格的宽度大于屏幕宽度,所以我创建了一个基于UICollectionViewFlowcustomFlowLayout 布局,返回正确的计算内容大小。

但是,这不起作用。当单元格的宽度小于屏幕宽度时,它可以工作。这是否意味着我们不能在垂直滚动时宽度超过屏幕宽度?

水平滚动也是一样,但是CollectionView的高度限制为屏幕高度。

有没有办法让它工作?

【问题讨论】:

我最近不得不重新审视它。我在这里创建了一个演示项目:github.com/izotx/ScrollableCollectionView 它使用嵌入在滚动视图中的集合视图以两种方式滚动内容。希望你会发现它很有用。 【参考方案1】:

正如其他人已经说过的,UICollectionView 只能使用流式布局滚动一个方向。但是,您无需创建自定义布局或使用第三方库即可非常轻松地完成此操作。

当您在故事板中展示您的视图时,您可以将您的 UICollectionView 嵌入到 UIScrollView 中。将滚动视图设置为水平滚动,UICollectionView 设置为垂直滚动。然后将UICollectionView.delaysContentTouches设置为true,这样触摸将传递到UIScrollView,而不是认为您正在尝试滚动collectionview。

当您设置UICollectionView 时,将其大小和单元格的大小设置为您实际希望它们的大小(比实际屏幕宽)并相应地布置它们。

现在在包含 UIViewController 的地方把这段代码放到视图生命周期中

    - (void)viewDidLayoutSubviews 
        self.myScrollView.contentSize = self.myCollectionView.frame.size;
    

这就是你要完成你所描述的事情所要做的一切。现在,您的滚动视图应该允许您水平滚动以查看整个单元格,并且您的 collectionView 应该垂直滚动您的单元格。

编程愉快。

【讨论】:

这对我有用,但请注意:此布局将强制 CollectionView 一次生成其所有单元格,因此此解决方案对于大量单元格是不切实际的。我最终需要找到一个不同的解决方案 (***.com/q/15549233/1418688),因为我的 CollectionView 非常大。 @AlexanderWinn,感谢您的反馈。链接的解决方案很棒。在这个特定的问题中,您实际上不需要加载比您需要的更多的单元格。我在连续可滚动的日历周(垂直小时)中使用它。所以它有潜在的无限单元格,我根据需要加载它们。链接的解决方案适用于带有行和列的集合视图,您需要在其中滚动两个方向(处于某种缩放状态)。这个问题更具体地针对具有单行的集合视图,其中每个单独的单元格都大于可视屏幕。不过很好的说明。 我应该在哪里添加延迟内容触摸? @johnny - 可能在 viewDidLoad 或情节提要或 xib 中(如果您正在使用)。 @Nerrolken 很好奇,为什么它会强制 CV 一次加载所有单元格?【参考方案2】:

我不确定我是否理解您的问题。

但如果您已经制作了自定义布局,请确保您已经实现:

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath;

并且您的布局属性框架和大小设置为“大单元”索引路径的正确值。

还要确保你已经实现了:

- (CGSize) collectionViewContentSize;

该方法返回集合 View 的 contentSize。如果 contentSize.width > youAppFrame.width 你应该有水平滚动。高度和垂直滚动相同。

还要确保您的 collectionView 允许滚动,并且您的布局使用正确准备:

- (void)prepareLayout

顺便说一句,对于您的布局,您是否重载了UICollectionViewLayoutUICollectionViewFlowLayout

【讨论】:

我正在继承 UICollectionViewFlowLayout... 我已经指定了 collectionViewContentSize。在preparelayout我设置itemsize [self setItemSize:CGSizeMake(10.0f*200.0f, 30)];我的要求是,单元格宽度高于屏幕宽度,并且行数超过屏幕高度。我不知道如何使用 uicollectionview 来实现这一点...【参考方案3】:

在您可以这样做之前,您必须使用不同类型的布局。流布局将其项目表示为列表,并根据可用宽度在单元格中跨越这些项目。 如果您想同时进行水平和垂直滚动,您需要以某种方式指定网格的列数。 FlowLayout 没有。一个简单的解决方案是创建 UICollectionViewLayout 的子类并覆盖 collectionViewContentSize 以使其将 width = 重新调整为一行单元格宽度的总和(这是需要知道你想要多少列的地方),加上任何额外的间距他们。如果您的单元格每列的大小相同,这将正常工作,类似于网格。

【讨论】:

【参考方案4】:

您应该将 UITableView 嵌入到 UIScrollView 中。 ScrollView 和 TableView 将具有相同的高度但不同的宽度。 这样 UITableView 会垂直滚动,UIScrollView 会水平滚动。

【讨论】:

【参考方案5】:

Xcode 11+,Swift 5。

我解决了我的问题,我准备好了video和code

【讨论】:

以上是关于UICollectionView 双向滚动的主要内容,如果未能解决你的问题,请参考以下文章

UICollectionView

UICollectionView 单元格在可见时不断重新加载

大 UICollectionViewCell 在滚动时消失

UICollectionView 未注册单元格

UiCollectionView 间距问题 - 快速

RFQuiltLayout 和 UICollectionView