#objective-c #cocoa #nstableview #nsscrollview
#objective-c #cocoa #nstableview #nsscrollview
Вопрос:
У меня есть NSTableView
встроенный в пользовательский NSScrollView
подкласс, в котором я иногда выполняю прокрутку программно, вот так:
[[self contentView] scrollToPoint:newOffset];
[self reflectScrolledClipView:[self contentView]];
Когда я делаю это, NSTableView
прокручивается нормально, но связанный с ним файл NSTableHeaderView
не перемещается вместе с ним. Однако, если я использую мышь и прокручиваю NSScrollView
нормально, они перемещаются вместе, как и должны.
Я полагаю, что, вероятно, где-то просто отсутствует одна строка, которая позволяет NSTableHeaderView
знать, что она тоже должна прокручиваться, но я не знаю, что это такое. Кто-нибудь может помочь?
Комментарии:
1. Вы пробовали использовать
-documentView
вместо-contentView
?2. @Bavarious Теперь у меня есть. Это не работает. 😛 Честно говоря, использование
-documentView
вместо-contentView
в любом случае не имеет большого смысла;-documentView
возвращаетNSTableView
, тогда как-contentView
возвращаетNSClipView
. В этом случае я почти уверен, что мне нуженNSClipView
.
Ответ №1:
Ну, я не знаю точно, какая черная магия происходит под капотом, когда вы прокручиваете NSScrollView
содержащий NSTableHeaderView
объект с помощью мыши, но, похоже, он обрабатывает это где-то внутри. Чтобы обойти это, я теперь только прокручиваю NSTableView
программно (переопределяя функции, которые будут обрабатывать пользовательский ввод), а затем прокручиваю NSTableHeaderView
сам, вот так:
NSTableHeader *header = [[self documentView] headerView];
[header setBoundsOrigin:NSMakePoint(newOffset.x,[header bounds].origin.y)];
Комментарии:
1. Черная магия заключается в том, что NSScrollView проверяет представление документа на наличие метода / свойства «headerView» и, если найдено, обрабатывает его таким образом. Это нигде не задокументировано, что я могу найти, кроме этого списка рассылки: lists.apple.com/archives/cocoa-dev/2009/Jun/msg01464.html
Ответ №2:
Я столкнулся с той же проблемой в NSTableView на основе ячеек с Swift 5 / macOS 14.
NSScrollView, заключающий в себе NSTableView, владеет как contentView, так и headerView NSTableView (и cornerView, который я не использую), и обычно отвечает за координацию их прокрутки.
- При прокрутке с помощью мыши внутренняя программа NSScrollView корректно обрабатывает прокрутку представления заголовка.
- При программной прокрутке NSClipView с использованием scroll(to:) reflectScrolledClipView NSScrollView не удается прокрутить заголовок.
Я использую этот протокол также для программной прокрутки 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)
}
}
}