我有一个嵌入在自定义NSTableView
子类中的NSScrollView
,其中我有时会以编程方式滚动,如下所示:
[[self contentView] scrollToPoint:newOffset];
[self reflectScrolledClipView:[self contentView]];
当我这样做时,NSTableView
滚动很好,但其相关的NSTableHeaderView
不会随之移动。但是,如果我使用鼠标并正常滚动NSScrollView
,它们会像他们应该的那样一起移动。
我想我可能只是错过了一条线,让NSTableHeaderView
知道它应该滚动,但我不知道那是什么。有人可以帮忙吗?
好吧,当你用鼠标滚动包含NSScrollView
的NSTableHeaderView
时,我不知道究竟是什么样的黑魔法在引擎盖下,但看起来它在某处内部处理它。为了避免这种情况,我现在只以编程方式滚动NSTableView
(通过覆盖将处理用户输入的函数),然后我自己滚动NSTableHeaderView
,如下所示:
NSTableHeader *header = [[self documentView] headerView];
[header setBoundsOrigin:NSMakePoint(newOffset.x,[header bounds].origin.y)];
我在使用Swift 5 / MacOS 14的基于单元的NSTableView上遇到了同样的问题。
包含NSTableView的NSScrollView拥有contentView和NSTableView的headerView(以及我不使用的cornerView),并且通常负责协调他们的滚动。
我使用此协议以编程方式滚动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)
}
}
}