我想检测UITableView
节标题何时捕捉到屏幕顶部,然后修改标题的高度,但我不知道该怎么做。任何人都可以帮忙吗?
5 回答
didEndDisplayingHeaderView
通过使用和willDisplayHeaderView
委托方法,我能够完成检测哪个标题卡在表格视图的顶部。这里的想法是,当我们滚动浏览表格视图的各个部分时,标题周围的行变得可见,我们可以使用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")
}
}
我去把我的评论变成代码,它的工作原理是:
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
}
}
所以你sectionIWant
用一个Int
and替换,当该部分的标题位于顶部时,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)
}
}
请注意,在这两个代码中都有一个defaultOffSet
which 是contentOffSet
on tableView
load,这是为了考虑到contentOffSet
在某些情况下它不是从 0 开始的——我不确定什么时候,但我之前确实遇到过这种情况。
派对迟到了,但查看所有回复并没有解决我的问题。
下面的做法,每一个都借鉴了一点,同时又增加了一个更通用且不固定的做法。
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard let visibleIndexs = self.tableView.indexPathsForVisibleRows,
!visibleIndexs.isEmpty else { return }
var visibleHeaders = [Int]()
visibleIndexs.forEach { anIndexPath in
if !visibleHeaders.contains(anIndexPath.section) {
visibleHeaders.append(anIndexPath.section)
}
}
visibleHeaders.forEach { header in
let headerView = tableView.headerView(forSection: header)
let headerOriginalFrame = self.tableView.rectForHeader(inSection: header)
if headerOriginalFrame != headerView?.frame {
//do something with top headerView
} else {
//do something else with all the others headerView(s)
}
}
}
事实证明,我对这个问题的解决方案非常有效且用途广泛。如果这对某人有帮助,我会很高兴
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let sectionPosition = tableView.rect(forSection: sectionIndex)
let translation = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
if let dataSource = dataSource,
scrollView.contentOffset.y >= sectionPosition.minY {
//Next section
guard dataSource.count - 1 > sectionIndex else { return }
sectionIndex += 1
} else if translation.y > 0,
scrollView.contentOffset.y <= sectionPosition.minY {
//Last section
guard sectionIndex > 0 else { return }
sectionIndex -= 1
}
这个解决方案对我有用。
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
}
}