以编程方式滚动到UICollectionView中的补充​​视图

Vap*_*olf 21 iphone ipad ios uicollectionview

UICollectionView用来分段显示照片.每个部分都有一个补充视图作为标题,并通过以下方法提供:viewForSupplementaryElementOfKind.

我的侧面有一个擦洗器,允许用户从一个部分跳到另一个部分.现在我正在滚动到该部分中的第一项使用scrollToItemAtIndexPath:atScrollPosition:animated:,但我真正想要的是滚动collectionView,以便该部分的标题位于屏幕的顶部,而不是第一个单元格.我没有看到一个明显的方法来做到这一点.你们中有人有工作吗?

我想我可以滚动到该部分的第一项,然后通过补充高度加上项目和标题之间的偏移来抵消它(如果它归结为那个(有一种方法可以滚动到contentView的点坐标)).但是,如果有一种更简单的方法,我想知道.

谢谢.

Ser*_*nko 38

不能scrollToItemAtIndexPath:atScrollPosition:animated它.

希望他们将scrollToSupplementaryElementOfKind:atIndexPath:在未来添加一种新方法,但就目前而言,唯一的方法是直接操作contentOffset.

下面的代码显示了如何使用FlowLayout将标题滚动到垂直顶部.您可以对水平滚动执行相同操作,或将此想法用于其他布局类型.

NSIndexPath *indexPath = ... // indexPath of your header, item must be 0

CGFloat offsetY = [collectionView layoutAttributesForSupplementaryElementOfKind:UICollectionElementKindSectionHeader atIndexPath:indexPath].frame.origin.y;

CGFloat contentInsetY = self.contentInset.top;
CGFloat sectionInsetY = ((UICollectionViewFlowLayout *)collectionView.collectionViewLayout).sectionInset.top;

[collectionView setContentOffset:CGPointMake(collectionView.contentOffset.x, offsetY - contentInsetY - sectionInsetY) animated:YES];
Run Code Online (Sandbox Code Playgroud)

请注意,如果您有非零contentInset(如在iOS 7中,当滚动视图在条形下方展开时),您需要从中减去它offsetY,如图所示.同样的sectionInset.

更新:

该代码假定布局处于准备好的"有效"状态,因为它使用它来计算偏移量.当集合视图显示其内容时,将准备布局.

[_collectionView.collectionViewLayout prepareLayout]当您需要滚动尚未显示的集合视图时(viewDidLoad例如),上面代码之前的调用可能会有所帮助.对layoutIfNeeded(在评论中建议的@Vrasidas)的调用也应该有效,因为它也准备了布局.

  • 这对我不起作用.它崩溃在layoutAttributes ...与`由于未捕获的异常终止应用程序'NSInternalInconsistencyException',原因:'索引路径([0,0])上的补充项的布局属性从<UICollectionViewLayoutAttributes:0x12c8d180>索引路径更改:([0 ,0]); 元素种类:(UICollectionElementKindSectionHeader); frame =(0 0; 0 0); to <UICollectionViewLayoutAttributes:0x12cc99e0> index path:([0,0]); 元素种类:(UICollectionElementKindSectionHeader); frame =(0 0; 492 60); 没有使布局失效'`任何想法? (2认同)

clo*_*ach 6

Swift中的解决方案,

let section: = 0 // Top
if let cv = self.collectionView {

    cv.layoutIfNeeded()

    let indexPath = NSIndexPath(forItem: 1, inSection: section)
    if let attributes =  cv.layoutAttributesForSupplementaryElementOfKind(UICollectionElementKindSectionHeader, atIndexPath: indexPath) {

        let topOfHeader = CGPointMake(0, attributes.frame.origin.y - cv.contentInset.top)
        cv.setContentOffset(topOfHeader, animated:true)
    }
}
Run Code Online (Sandbox Code Playgroud)

Gene De Lisa的道具:http://www.rockhoppertech.com/blog/scroll-to-uicollectionview-header/

  • 此代码有效,但正如本页上的其他解决方案所建议的那样,您需要在调用“cv.layoutAttributesForSupplementaryElementOfKind”之前放置“cv.layoutIfNeeded()”函数,否则如果 cv 未准备好,此代码将崩溃。 (2认同)