5

のセクションのヘッダーUITableViewが現在フローティングであるかどうかを検出する方法はありますか?テーブルビューがフローティングの場合にのみ、ヘッダー位置までスクロールしたい。

前もって感謝します!

4

6 に答える 6

7

セクションの最初のセルが表示されなくなった場合、ヘッダーはフローティングになります。それで:

NSIndexPath *topCellPath = [[self.tableView indexPathsForVisibleRows] objectAtIndex:0];
if (topCellPath.row != 0)
{
    // Header must be floating!
}

scrollToRowAtIndexPath:atScrollPosition:animated:でインデックスパスにスクロールし、スクロール位置を-で同様の効果を得ることができUITableViewScrollPositionNoneます。セクションの最初のセルがすでに画面に表示されている場合、これはスクロールしません。

于 2012-06-26T14:18:40.197 に答える
1

これは機能します。

@implementation UITableView (rrn_extensions)

-(BOOL)rrn_isFloatingSectionHeaderView:(UITableViewHeaderFooterView *)view {
    NSNumber *section = [self rrn_sectionForHeaderFooterView:view];
    return [self rrn_isFloatingHeaderInSection:section.integerValue];
}

-(BOOL)rrn_isFloatingHeaderInSection:(NSInteger)section {
    CGRect frame = [self rectForHeaderInSection:section];
    CGFloat y = self.contentInset.top + self.contentOffset.y;
    return y > frame.origin.y;
}

-(NSNumber *)rrn_sectionForHeaderFooterView:(UITableViewHeaderFooterView *)view {
    for (NSInteger i = 0; i < [self numberOfSections]; i++) {
        CGPoint a = [self convertPoint:CGPointZero fromView:[self headerViewForSection:i]];
        CGPoint b = [self convertPoint:CGPointZero fromView:view];
        if (a.y == b.y) {
            return @(i);
        }
    }
    return nil;
}

@end
于 2016-10-07T12:31:18.120 に答える
1

@robdashnashの回答の迅速なポートを追加する

extension UITableView
{
     func isFloatingSectionHeader( view:UITableViewHeaderFooterView )->Bool
     {
          if let section = section( for:view )
          {
              return isFloatingHeaderInSection( section:section )
          }
          return false
      }

     func isFloatingHeaderInSection( section:Int )->Bool
     {
         let frame = rectForHeader( inSection:section )
         let y = contentInset.top + contentOffset.y
         return y > frame.origin.y
     }

     func section( for view:UITableViewHeaderFooterView )->Int?
     {
         for i in stride( from:0, to:numberOfSections, by:1 )
         {
             let a = convert( CGPoint.zero, from:headerView( forSection:i ) )
             let b = convert( CGPoint.zero, from:view )
             if a.y == b.y
             {
                 return i
             }
         }
         return nil
     }
 }
于 2017-06-15T18:26:25.650 に答える
1

iOS11.0+ソリューションUITableViewsと同様にUICollectionViews

どちらの場合も、このscrollViewDidScroll方法を使用してください。このプロパティを使用currentHeaderして、上部に表示されている現在のヘッダーを保存できます。HEIGHT_OF_HEADER_VIEW自分で指定する必要がある値です。

にとってUITableView

private var currentHeader: UITableViewHeaderFooterView? {
    willSet {
        // Handle `old` header
    } didSet {
        // Hanlde `new` header
    }
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let point = CGPoint(x: 0, y: HEIGHT_OF_HEADER_VIEW + tableView.contentOffset.y + tableView.adjustedContentInset.top)
    guard let path = tableView.indexPathForRow(at: point) else {
        return
    }

    let section = path.section
    let rect = tableView.rectForHeader(inSection: section)
    let converted = tableView.convert(rect, to: tableView.superview)
    let safeAreaInset = tableView.safeAreaInsets.top

    // Adding 1 offset because of large titles that sometimes cause slighly wrong converted values
    guard converted.origin.y <= safeAreaInset,
        let header = tableView.headerView(forSection: section) else {
        return
    }
    currentHeader = header
}

にとってUICollectionView

private var currentHeader: UICollectionReusableView? {
    willSet {
        // Handle `old` header
    } didSet {
        // Handle `new` header
    }
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let x = (collectionView.collectionViewLayout as? UICollectionViewFlowLayout)?.sectionInset.left ?? 0
    let point = CGPoint(x: x, y: HEIGHT_OF_HEADER_VIEW + collectionView.contentOffset.y + collectionView.adjustedContentInset.top)

    guard let path = collectionView.indexPathForItem(at: point),
        let rect = collectionView.layoutAttributesForSupplementaryElement(ofKind: UICollectionView.elementKindSectionHeader, at: IndexPath(row: 0, section: path.section))?.frame else {
        return
    }

    let converted = collectionView.convert(rect, to: collectionView.superview)
    let safeAreaInset = collectionView.safeAreaInsets.top

    guard converted.origin.y <= safeAreaInset,
        let header = collectionView.supplementaryView(forElementKind: UICollectionView.elementKindSectionHeader, at: IndexPath(row: 0, section: path.section)) else {
        return
    }
    currentHeader = header
}
于 2020-06-01T12:53:54.833 に答える
0

最初に、セクションヘッダービューの元の四角形を保存できます。

 headerView.originalPoint = [tableView rectForHeaderInSection:section].origin;

そしてscrollViewDidScroll:scrollView、ヘッダーにメッセージを送信します。

ヘッダービューで

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
   BOOL isFloating = self.frame.origin.y > self.originalPoint.y;
   if (isFloating) {
       //DO what you want
   }
}
于 2016-05-18T02:00:21.293 に答える
0

コードは私のために働きます。

- (BOOL)isSection0HeaderSticky {
    CGRect originalFrame = [self.listTableView rectForHeaderInSection:0];

    UIView *section0 = [self.listTableView headerViewForSection:0];

    if (originalFrame.origin.y < section0.frame.origin.y) {
        return  YES;
    }
    return NO;
}
于 2017-04-16T11:56:36.030 に答える