启用了预览和分页的UICollectionView

Rpr*_*ata 11 cocoa-touch uikit ios6 uicollectionview

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

它显示了卡片中的详细应用信息,并且它被分页.当我在中间的一张活动卡和滚动视图的分页行为仍然完好无损时,我仍然坚持如何制作上一张和下一张卡片.

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

干杯,

Rendy Pranata

Mik*_*e M 7

问题:UICollectionView作为UIScrollView的子类实际上是通过bounds.size的步幅来动画其边界.虽然这可能意味着你所要做的就是在保持框架更大的同时减小边界,但遗憾的是UICollectionView不会渲染任何超出其当前边界的单元格...破坏预览效果.

解决方案:

  1. 创建一个UICollectionView,将分页设置为NO并使用所需的帧.
  2. 创建小于UICollectionView的框架/边界的UICollectionViewCells.在此阶段,下一个单元格的一部分应显示在框架中.在执行下面的其他步骤之前,这应该是可见的.
  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);

}
Run Code Online (Sandbox Code Playgroud)


Bre*_*nan 0

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

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

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

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

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