检测UITableView节标题何时捕捉到屏幕顶部

Pak*_*hat 3 uitableview ios swift uitableviewsectionheader

我想检测UITableView节标题何时贴紧在屏幕顶部,然后修改标题的高度,但是我不知道该怎么做。有人可以帮忙吗?

小智 5

通过使用didEndDisplayingHeaderViewwillDisplayHeaderView委托方法,我能够完成检测哪个标头卡在表格视图顶部的功能。这里的想法是,当我们滚动浏览表视图的各个部分时,标题周围的行变得可见,并且可以使用捕获所有可见行的索引路径tableView.indexPathsForVisibleRows。根据我们是向上滚动还是向下滚动,我们将屏幕上的第一个或最后一个indexPath与刚刚出现/消失的视图的索引路径进行比较。

//pushing up
func tableView(_ tableView: UITableView,
               didEndDisplayingHeaderView view: UIView,
               forSection section: Int) {

    //lets ensure there are visible rows.  Safety first!
    guard let pathsForVisibleRows = tableView.indexPathsForVisibleRows,
        let lastPath = pathsForVisibleRows.last else { return }

    //compare the section for the header that just disappeared to the section
    //for the bottom-most cell in the table view
    if lastPath.section >= section {
        print("the next header is stuck to the top")
    }

}

//pulling down
func tableView(_ tableView: UITableView,
               willDisplayHeaderView view: UIView,
               forSection section: Int) {

    //lets ensure there are visible rows.  Safety first!
    guard let pathsForVisibleRows = tableView.indexPathsForVisibleRows,
        let firstPath = pathsForVisibleRows.first else { return }

    //compare the section for the header that just appeared to the section
    //for the top-most cell in the table view
    if firstPath.section == section {
        print("the previous header is stuck to the top")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 伟大而强大的解决方案! (2认同)

Ben*_*Ong 2

我把我的评论写成代码,它的工作原理如下:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {

    if scrollView == yourTableView {
        if yourTableView.rectForHeader(inSection: <#sectionIWant#>).origin.y <= tableView.contentOffset.y-defaultOffSet.y &&
            yourTableView.rectForHeader(inSection: <#sectionIWant#>+1).origin.y > tableView.contentOffset.y-defaultOffSet.y {
            print("Section Header I want is at top")
        }
    } else {
        //Handle other scrollViews here
    }
}
Run Code Online (Sandbox Code Playgroud)

所以你sectionIWant用 an替换Int,当该部分的标题位于顶部时,print将运行。注意,这yourTableView不是 的参数scrollViewDidScroll,因此你必须保留对其他地方的引用UITableView并在此处使用它。

或者,如果您想不断更新哪个部分标题位于顶部,您可以使用:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {

    if scrollView == yourTableView {
        var currentSection = 0
        while !(tableView.rectForHeader(inSection: currentSection).origin.y <= (tableView.contentOffset.y-defaultOffSet.y) &&
            tableView.rectForHeader(inSection: currentSection+1).origin.y > (tableView.contentOffset.y)-defaultOffSet.y) {
                if tableView.contentOffset.y <= tableView.rectForHeader(inSection: 0).origin.y {
                    break   //Handle tableView header - if any
                }
                currentSection+=1
                if currentSection > tableView.numberOfSections-2 {
                    break   //Handle last section
                }
        }
        print(currentSection)
    }

}
Run Code Online (Sandbox Code Playgroud)

请注意,在两个代码中都有一个defaultOffSetcontentOffSet加载时tableView的 ,这是为了考虑到contentOffSet在某些情况下 不是从 0 开始 - 我不确定什么时候,但我以前确实遇到过这种情况。