启用了预览和分页的UICollectionView

时间:2013-02-07 06:04:51

标签: cocoa-touch ios6 uikit 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

2 个答案:

答案 0 :(得分:7)

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

解决方案:

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

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

答案 1 :(得分:0)

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

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

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

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

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