编程滚动到内UICollectionView一个补充视图(Programmatically scro

2019-09-01 05:48发布

我使用UICollectionView显示在部分照片。 每个部分具有作为报头的补充视图和通过所述方法被提供: viewForSupplementaryElementOfKind

我有,允许用户从一节跳转到节中的侧洗涤。 对于我现在滚动的第一个项目中使用的部分scrollToItemAtIndexPath:atScrollPosition:animated: ,但我真正想要的是滚动的CollectionView,使得节的头是在屏幕上,而不是第一个单元格的顶部。 我没有看到一个明显的法做到这一点。 做任何你周围的工作?

我想我可以滚动到节的第一个项目,然后抵消由补充的高度再加上如果它归结到(有滚动来点内容查看坐标的方法)的项目和头之间的偏移。 但是,如果有一个更简单的方法,我想知道。

谢谢。

Answer 1:

不能使用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];

需要注意的是,如果你有非零contentInset (如适用于iOS 7,当滚动视图下展开吧),你需要从减去它offsetY ,如图所示。 同为sectionInset

更新:

该代码假定的布局是在事先准备好的,“有效”状态,因为它使用它来计算偏移量。 当集合视图呈现其内容的布局准备。

以呼叫[_collectionView.collectionViewLayout prepareLayout]代码之前,当你需要滚动它尚未呈现集合视图(从上面可以帮助viewDidLoad说的)。 要将呼叫layoutIfNeeded (如@Vrasidas的意见建议)应该工作了,因为它也准备布局。



Answer 2:

解决方案在斯威夫特,

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

道具基因德丽莎: http://www.rockhoppertech.com/blog/scroll-to-uicollectionview-header/



Answer 3:

// scroll to selected index
NSIndexPath* cellIndexPath = [NSIndexPath indexPathForItem:0 inSection:sectionIndex];
UICollectionViewLayoutAttributes* attr = [self.collectionView.collectionViewLayout layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:cellIndexPath];
UIEdgeInsets insets = self.collectionView.scrollIndicatorInsets;

CGRect rect = attr.frame;
rect.size = self.collectionView.frame.size;
rect.size.height -= insets.top + insets.bottom;
CGFloat offset = (rect.origin.y + rect.size.height) - self.collectionView.contentSize.height;
if ( offset > 0.0 ) rect = CGRectOffset(rect, 0, -offset);

[self.collectionView scrollRectToVisible:rect animated:YES];


Answer 4:

一件事的解决方案,不管理是如果你是钉扎节头。 该方法与未锁定的头做工精细,但如果你的头被固定,而滚动到当前部分之上的部分,它将一旦节头出现停止(这将是你的部分底部行)。 这可能是在某些情况下,可取的,但我认为我们的目标是把部分的顶部在屏幕的顶部。

在这种情况下,你需要采取上述方法并调整了一下。 例如:

UICollectionView *cv = self.collectionView;
CGFloat contentInsetY = cv.contentInset.top;
CGFloat offsetY = [cv layoutAttributesForItemAtIndexPath:ip].frame.origin.y;
CGFloat sectionHeight =
[cv layoutAttributesForSupplementaryElementOfKind:UICollectionElementKindSectionHeader atIndexPath:ip].frame.size.height;
[cv setContentOffset:CGPointMake(cv.contentOffset.x, offsetY - contentInsetY - sectionHeight) animated:YES];

现在你基本上是滚动的部分可见,少了节头的高度的第一排。 这将使节头你在哪里与固定头部希望它这样滚动的方向将不再重要顶部。 我没有第插图测试。



文章来源: Programmatically scroll to a supplementary view within UICollectionView