【问题标题】:UICollectionView with preview and paging enabled启用预览和分页的 UICollectionView
【发布时间】:2013-02-07 06:04:51
【问题描述】:

在 App Store 中显示搜索结果时,我试图模仿 Apple 的内容。 (参考:http://searchengineland.com/apple-app-search-shows-only-one-result-at-a-time-133818

它像卡片中的详细应用程序信息一样显示,并且是分页的。当中间有一张活动卡片并且滚动视图的分页行为仍然完好无损时,我被困在如何制作上一张和下一张卡片。

我尝试使用 UICollectionView 并将 clipSubviews 设置为 NO,希望它会显示上一页和下一页,但是一旦单元格离开屏幕,单元格就会被隐藏(从视图层次结构中删除) 并且不显示。我认为这就是 UICollectionView 的享元模式(UICollectionView 的行为)。有什么可能的想法吗?

干杯,

伦迪·普拉纳塔

【问题讨论】:

  • 你有自定义的UICollectionViewFlowLayout吗?
  • 是的...我试过了,它在某些时候有效,但在用户体验方面,它仍然感觉很尴尬,而且不像通过设置 pagingEnabled YES 可以做到的那样流畅
  • 如果您找到任何解决此问题的方法,请告诉我。我这里也一样。

标签: cocoa-touch ios6 uikit uicollectionview


【解决方案1】:

问题:作为 UIScrollView 的子类的 UICollectionView 本质上以 bounds.size 的步幅为其边界设置动画。虽然这可能意味着您所要做的就是在保持框架更大的同时减小边界,但不幸的是 UICollectionView 不会呈现超出其当前边界的任何单元格...破坏您的预览效果。

解决方案:

  1. 创建一个 UICollectionView,将分页设置为 NO 并使用所需的框架。
  2. 创建小于 UICollectionView 的框架/边界的 UICollectionViewCell。在这个阶段,下一个单元格的一部分应该显示在框架中。在执行以下其他步骤之前,这应该是可见的。
  3. 添加一个collectionView.contentInset.left和right(我假设你的布局是水平的)等于contentOffsetValue方法(为简单起见如下所示),以便将第一个和最后一个单元格对齐到中间。
  4. 创建一个 UICollectionViewFlowLayout 覆盖提供停止点的方法,如下所示:

像这样:

-(CGFloat)contentOffsetValue
{
    return self.collectionView.bounds.size.width * 0.5f - self.itemSize.width * 0.5f;
}

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{

    static float EscapeVelocity = 0.5f; // otherwise snap back to the middle
    NSArray* layoutAttributesArray = [self layoutAttributesForElementsInRect:self.collectionView.bounds];

    if(layoutAttributesArray.count == 0)
        return proposedContentOffset;

    CGFloat currentBoundsCenterX = self.collectionView.contentOffset.x + self.collectionView.bounds.size.width * 0.5f;


    UICollectionViewLayoutAttributes* candidateNextLayoutAttributes = layoutAttributesArray.firstObject;


    for (UICollectionViewLayoutAttributes* layoutAttributes in layoutAttributesArray)
    {
        if ((layoutAttributes.representedElementCategory != UICollectionElementCategoryCell) ||
            (layoutAttributes == candidateNextLayoutAttributes)) // skip the first comparison
            continue;

        if(velocity.x > EscapeVelocity || velocity.x < -(EscapeVelocity))
        {
            if(velocity.x > EscapeVelocity && layoutAttributes.center.x > candidateNextLayoutAttributes.center.x)
            {

                candidateNextLayoutAttributes = layoutAttributes;
            }

            else if (velocity.x < -(EscapeVelocity) && layoutAttributes.center.x < candidateNextLayoutAttributes.center.x)
            {

                candidateNextLayoutAttributes = layoutAttributes;
            }
        }
        else
        {
            if(fabsf(currentBoundsCenterX - layoutAttributes.center.x) < fabsf(currentBoundsCenterX - candidateNextLayoutAttributes.center.x))
            {

                candidateNextLayoutAttributes = layoutAttributes;
            }
        }   
    }
    return CGPointMake(candidateNextLayoutAttributes.center.x - self.collectionView.bounds.size.width * 0.5f, proposedContentOffset.y);

}

【讨论】:

  • 这似乎没有捕捉到第一个和最后一个单元格
  • 那是因为集合视图没有“空间”来导航。它在上面的代码之外。尝试在集合视图本身上设置“contentInset”。
  • 在我关闭收藏视图上的分页之前,它对我不起作用。
  • 谢谢!我更新了上面的文字。另外,你可以看看我写的关于这个主题的另一个答案:stackoverflow.com/questions/20496850/…
  • 谢谢!这是我在那里找到的最正确的答案!完美!
【解决方案2】:

我只是整理了一个示例项目,展示了如何做到这一点。我创建了一个比屏幕的 320 点宽 100 点的容器视图。然后我将 UICollectionView 放入该容器中。这会将屏幕两侧的所有内容偏移 50 个点。

然后是一个内容单元格,它只有一个背景和一个标签,因此您可以直观地识别正在发生的事情。在左侧和右侧有空单元格。在 viewDidLoad 方法中,内容插入在左右两侧设置为负值,以使空单元格现在滚动到视图中。您可以根据自己的喜好调整插图。

这非常接近地模仿了这种行为。要获得下面的标签,就像在示例中一样,您可以简单地检查 contentOffset 值以确定哪个单元格处于焦点。为此,您需要使用 UIScrollViewDelegate,它是 UICollectionView 的一部分。

https://github.com/brennanMKE/Interfaces/tree/master/ListView

您会注意到这个示例项目有 2 个集合视图。一种是正常的水平流布局,而另一种具有较大单元格的是模仿您提到的示例的那种。

【讨论】:

  • 我简化了布局,因此视图不使用容器视图,也不必比屏幕宽。 github.com/brennanMKE/Interfaces/tree/master/ListView
  • 我从链接下载了代码,但我没有看到 Rpranata 提到的任何内容...我误解了这个问题吗?
  • 这不会分页。
猜你喜欢
  • 2014-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多