这是我解决这个问题的方法。我想知道是否有更简单的方法来做到这一点。
请注意,这只会在你的头文件是UITableViewHeaderFooterView时才起作用。如果您使用UITableViewCell作为标题,则不行。如果您使用的是UITableViewCell,则tableView.headerView(forSection:indexPathForVisibleRow.section)将返回nil。
为了在tableView停止滚动时隐藏固定标题并在tableView开始再次滚动时让它们重新出现,请覆盖这四个scrollView委托方法。
在前两个(scrollViewWillBeginDragging和scrollViewWillBeginDecelerating)中,获取可见行的第一部分的部分标题并确保其未隐藏。
在后面的两个委托方法中,请检查以查看每个可见行,该行的标题框不与行单元的框架重叠。如果是,那么这是一个固定标题,我们在延迟后隐藏它。我们需要确保在移除固定标题之前,scrollView不会继续拖动,这与用户抬起手指但滚动视图继续滚动时的情况相同。同样由于时间延迟,我们检查了scrollView在删除之前没有拖动,以防止用户在滚动停止后不到0.5秒时再次开始滚动。
override func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
showPinnedHeaders()
}
override func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
showPinnedHeaders()
}
override func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
removePinnedHeaders()
}
override func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
removePinnedHeaders()
}
private func showPinnedHeaders() {
for section in 0..<totalNumberOfSectionsInYourTableView {
tableView.headerView(forSection: section)?.isHidden = false
}
}
private func removePinnedHeaders() {
if let indexPathsForVisibleRows = tableView.indexPathsForVisibleRows {
if indexPathsForVisibleRows.count > 0 {
for indexPathForVisibleRow in indexPathsForVisibleRows {
if let header = tableView.headerView(forSection: indexPathForVisibleRow.section) {
if let cell = tableView.cellForRow(at: indexPathForVisibleRow) {
if header.frame.intersects(cell.frame) {
let seconds = 0.5
let delay = seconds * Double(NSEC_PER_SEC)
let dispatchTime = DispatchTime.now() + Double(Int64(delay))/Double(NSEC_PER_SEC)
DispatchQueue.main.asyncAfter(deadline: dispatchTime, execute: {
if !self.tableView.isDragging && header.frame.intersects(cell.frame) {
header.isHidden = true
}
})
}
}
}
}
}
}
}
另外添加removePinnedHeaders()来viewDidAppear()和其他任何旋转或键盘边框改变方法,将滚动鼠标的tableView。