将UICollectionView滚动到节标题视图

时间:2014-02-28 16:13:03

标签: ios iphone uicollectionview

下面的代码滚动到UICollectionView中的右侧单元格,但在我的情况下,部分标题视图隐藏在UINavigationBar后面。我相信我应该使用scrollRectToVisible而我的问题是,当给定CGRect中的numberOfRows变量时,计算section(y位置)的正确方法是什么

- (void)scrollToPricing:(NSUInteger)row {

    [self.collectionView scrollToItemAtIndexPath:
      [NSIndexPath indexPathForItem:0 
                          inSection:row] 
                   atScrollPosition:UICollectionViewScrollPositionTop 
                           animated:YES];
}

8 个答案:

答案 0 :(得分:14)

似乎所有答案都过于复杂。这对我有用:

let attributes = self.collectionView.collectionViewLayout.layoutAttributesForSupplementaryViewOfKind(UICollectionElementKindSectionHeader, atIndexPath: NSIndexPath(forItem: 0, inSection: section))

self.collectionView.setContentOffset(CGPointMake(0, attributes!.frame.origin.y - self.collectionView.contentInset.top), animated: true)

斯威夫特3:

if let attributes = collectionView.collectionViewLayout.layoutAttributesForSupplementaryView(ofKind: UICollectionElementKindSectionHeader, at: IndexPath(item: 0, section: section)) {
    collectionView.setContentOffset(CGPoint(x: 0, y: attributes.frame.origin.y - collectionView.contentInset.top), animated: true)
}

答案 1 :(得分:10)

我认为这可能会对你有所帮助

UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];

然后,您可以通过attributes.frame

访问该位置

答案 2 :(得分:5)

首先,在部分中获取标题的框架:

- (CGRect)frameForHeaderForSection:(NSInteger)section {
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:1 inSection:section];
    UICollectionViewLayoutAttributes *attributes = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath];
    CGRect frameForFirstCell = attributes.frame;
    CGFloat headerHeight = [self collectionView:_collectionView layout:_layout referenceSizeForHeaderInSection:section].height;
    return CGRectOffset(frameForFirstCell, 0, -headerHeight);
}

注意:我只为1设置了值indexPath.item。您可能需要将其更改为适合您的实现的内容。

然后,将UIScrollView滚动到标题顶部的点:

- (void)scrollToTopOfSection:(NSInteger)section animated:(BOOL)animated {
    CGRect headerRect = [self frameForHeaderForSection:section];
    CGPoint topOfHeader = CGPointMake(0, headerRect.origin.y - _collectionView.contentInset.top);
    [_collectionView setContentOffset:topOfHeader animated:animated];
}

注意:您必须减去contentInset,否则它将被丢弃,您的滚动视图将滚动到状态栏和/或导航栏后面。

答案 3 :(得分:1)

// 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];

答案 4 :(得分:1)

基于@pixelfreak答案

Swift 4.2 + iOS 11 Safe Area支持(适用于iPhone X及更高版本)

if let attributes = collectionView.layoutAttributesForSupplementaryElement(ofKind: UICollectionView.elementKindSectionHeader, at: IndexPath(item: 0, section: section)) {
    var offsetY = attributes.frame.origin.y - collectionView.contentInset.top
    if #available(iOS 11.0, *) {
        offsetY -= collectionView.safeAreaInsets.top
    }
    collectionView.setContentOffset(CGPoint(x: 0, y: offsetY), animated: true) // or animated: false
}
  

快乐编码

答案 5 :(得分:1)

我发现接受的答案不再正常工作(2个标题粘在一起),尤其是在必须向上滚动收集视图时(向下仍然可以正常工作)。

以下代码在任一方向上均可正常运行:

 <a href="javascript:helpme('base');">Base Currency</a><br>
   <font size="-1">(choose one; most popular<br>choices appear at the top)</font>
   <select name="b">
      <option value="USD">U.S. Dollars
   <option value="CAD">Canadian Dollars
   <option value="EUR">European Euros
   <option value="GBP">British Pounds
   <option value="JPY">Japanese Yen

<a href="javascript:helpme('targets');">Target Currencies</a><br>
   <font size="-1">(choose one or more)</font>
   <br>
   <select name="c" multiple size=10>
      <option value="USD">U.S. Dollars
   <option value="CAD">Canadian Dollars
   <option value="EUR">European Euros
   <option value="GBP">British Pounds

 <a href="javascript:helpme('horizon');">Choose Time Horizon</a>
   <br>
   <select name="rd">
   <option value="" selected>Exact Time Period
   <option value="1">Last Trading Day
   <option value="7">Last 7 Days
   <option value="28">Last 28 Days

  <a href="javascript:helpme('horizon');">Choose Time Horizon</a>
   <br>
   <select name="rd">
   <option value="" selected>Exact Time Period
   <option value="1">Last Trading Day
   <option value="7">Last 7 Days
   <option value="28">Last 28 Days
   </select><br>&nbsp;<br>
   To use start and end date,<br>
   select "Exact Time Period" in the<br>
   "Choose Time Horizon" menu.<br>
   <a href="javascript:helpme('time');">Start Date</a><br>
   <input type=text size=2 name="fd" value="1" maxlength=2>
   <select name="fm">
   <option selected value="1">Jan
   <option value="2">Feb
   <option value="3">Mar
   <option value="4">Apr
   <option value="5">May
   <option value="6">Jun
   <option value="7">Jul
   <option value="8">Aug
   <option value="9">Sep
   <option value="10">Oct
   <option value="11">Nov
   <option value="12">Dec
   </select>
   <input type=text size=4 name="fy" value="2019" maxlength=4>
   <br>&nbsp;<br>
   <a href="javascript:helpme('time');">End Date</a><br>
   <input type=text size=2 name="ld" value="31" maxlength=2>
   <select name="lm">
   <option value="1">Jan
   <option value="2">Feb
   <option value="3">Mar
   <option value="4">Apr
   <option value="5">May
   <option value="6">Jun
   <option value="7">Jul
   <option value="8">Aug
   <option value="9">Sep
   <option value="10">Oct
   <option value="11">Nov
   <option selected value="12">Dec
   </select>

 <a href="javascript:helpme('tables');">Table Style</a>
   <br>
   <select name="f">
   <option value="HTML">HTML
   <option value="HTML2" selected>HTML+CSS
   <option value="plain">plain text
   <option value="Excel">Microsoft Excel
   <option value="LaTeX">LaTeX table
   <option value="csv">CSV spreadsheet
   <option value="tab">Tab spreadsheet
   </select>

答案 6 :(得分:0)

// [myCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:index_of_sec] atScrollPosition:UICollectionViewScrollPositionTop animated:YES];

Below code will fix your problem, as i have faced same issue and used this solution developed by me instead of above commented code.

UICollectionViewLayoutAttributes *attributes = [myCollectionView layoutAttributesForItemAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:index_of_sec]];
        CGRect rect = attributes.frame;
        [myCollectionView setContentOffset:CGPointMake(myCollectionView.frame.origin.x, rect.origin.y - HEIGHT_OF_YOUR_HEADER) animated:YES];

答案 7 :(得分:0)

最简单的方法是使用部分标题 frame.origin.xframe.origin.y,然后将部分标题 height height创建一个CGRect以滚动到。

let sectionHeaderAttributes: UICollectionViewLayoutAttributes = self.collectionView.layoutAttributesForItem(at: scrollToIndexPath)!;
let itemAttributes: UICollectionViewLayoutAttributes = self.collectionView.layoutAttributesForSupplementaryElement(ofKind: UICollectionElementKindSectionHeader, at: scrollToIndexPath)!;

let combinedFrame: CGRect = CGRect(x: sectionHeaderAttributes.frame.origin.x, y: sectionHeaderAttributes.frame.origin.y, width: sectionHeaderAttributes.frame.width, height: sectionHeaderAttributes.frame.height + itemAttributes.frame.height);

collectionView.scrollRectToVisible(combinedFrame, animated: false);
相关问题