のセクションのヘッダーUITableView
が現在フローティングであるかどうかを検出する方法はありますか?テーブルビューがフローティングの場合にのみ、ヘッダー位置までスクロールしたい。
前もって感謝します!
のセクションのヘッダーUITableView
が現在フローティングであるかどうかを検出する方法はありますか?テーブルビューがフローティングの場合にのみ、ヘッダー位置までスクロールしたい。
前もって感謝します!
セクションの最初のセルが表示されなくなった場合、ヘッダーはフローティングになります。それで:
NSIndexPath *topCellPath = [[self.tableView indexPathsForVisibleRows] objectAtIndex:0];
if (topCellPath.row != 0)
{
// Header must be floating!
}
scrollToRowAtIndexPath:atScrollPosition:animated:
でインデックスパスにスクロールし、スクロール位置を-で同様の効果を得ることができUITableViewScrollPositionNone
ます。セクションの最初のセルがすでに画面に表示されている場合、これはスクロールしません。
これは機能します。
@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
@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
}
}
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
}
最初に、セクションヘッダービューの元の四角形を保存できます。
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
}
}
コードは私のために働きます。
- (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;
}