我在使用 Swift 5 / MacOS 14 的基于单元的 NSTableView 上遇到了同样的问题。
包含 NSTableView 的 NSScrollView 拥有 NSTableView 的 contentView 和 headerView(以及我不使用的cornerView),并且通常负责协调它们的滚动。
- 当使用鼠标滚动时,NSScrollView 内部的魔法会正确处理标题视图的滚动。
- 当使用 scroll(to:) + reflectScrolledClipView 以编程方式滚动 NSClipView 时,NSScrollView 无法滚动 headerView。
我也使用此协议以编程方式滚动 headerView,这允许我使用此协议以编程方式滚动:
extension NSTableView : ScrollingProtocol {
func getScrollView() -> NSScrollView? {
return enclosingScrollView
}
func getVisibleOrigin() -> NSPoint? {
return enclosingScrollView?.documentVisibleRect.origin
}
func scrollToOrigin(_ targetOrigin: NSPoint) {
guard let currentOrigin = getVisibleOrigin(),
let scrollView = enclosingScrollView
else { return }
if (!NSEqualPoints(targetOrigin, currentOrigin)) {
let clipView = scrollView.contentView
clipView.scroll(to: targetOrigin)
// Workaround because NSClipView.scroll(to:) does not scroll
// the headerView of NSTableView
if let headerView = headerView {
let x = targetOrigin.x
let y = headerView.bounds.origin.y
if let headerClipView = headerView.superview as? NSClipView {
headerClipView.scroll(to: NSMakePoint(x, y))
}
}
scrollView.reflectScrolledClipView(clipView)
}
}
}