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

时间:2017-01-16 05:47:49

标签: ios swift uitableview uitableviewsectionheader

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

3 个答案:

答案 0 :(得分:4)

通过使用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")
    }
}

答案 1 :(得分:1)

我开始对代码进行评论,它的工作原理如下:

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if tableView.rectForHeader(inSection: 0).origin.y <= tableView.contentOffset.y-defaultOffSet.y &&
        tableView.rectForHeader(inSection: 1).origin.y > tableView.contentOffset.y-defaultOffSet.y {
        print("Section Header I want is at top")
    }
}

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

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

override func scrollViewDidScroll(_ scrollView: UIScrollView) {
    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)
}

请注意,在这两个代码中,defaultOffSet都是加载contentOffSet的{​​{1}},这是考虑到tableView无法启动在某些情况下为0 - 我不确定何时但我确实遇到过这种情况。

答案 2 :(得分:0)

此解决方案对我有用。

func scrollViewDidScroll(_ scrollView: UIScrollView) {
  self.visibleHeaders.forEach { header in
    let headerOriginalFrame = self.myTableView.rectForHeader(inSection: header.tag)
    let headerCurrentFrame = header.frame
    let fixed = headerOriginalFrame != headerCurrentFrame
    // Do things you want
  }
}

这里是完整的源代码。 https://github.com/jongwonwoo/CodeSamples/blob/master/TableView/TableviewFixedHeader/Tableview/ViewController.swift