My ultmate goal in this OSX app is to sync the vertical scroll of 2 NSTableViews.
I've browsed a lot of material, but could not find a comprehensive solution.
There is an advice to use notification of bounds changes from the scrollView of the NSTableView
which leads to this :
h ttp://borkware.com/quickies/one?topic=NSScrollView
So, I am trying to use NSViewBoundsDidChangeNotification, in the following code
dataTableScrollView.contentView.postsBoundsChangedNotifications = true
NotificationCenter.default.addObserver(self, selector: #selector(boundsDidChangeNotification), name: .NSViewBoundsDidChangeNotification, object: dataTableScrollView.contentView)
I get a compiler error:
Type 'NSNotification.Name?' has no member 'NSViewBoundsDidChangeNotification'
So, looking at doc, I found the NSNotification.Name property
https://developer.apple.com/documentation/foundation/nsnotification
boundsDidChangeNotification
Type Property
boundsDidChangeNotification
Posted whenever the NSView’s bounds rectangle changes to a new value independently of the frame rectangle, but only when the view’s postsBoundsChangedNotifications property is true.
Declaration
class let boundsDidChangeNotification: NSNotification.Name
Trying code with
dataTableScrollView.contentView.postsBoundsChangedNotifications = true
NotificationCenter.default.addObserver(self, selector: #selector(boundsDidChangeNotification), name: .boundsDidChangeNotification, object: dataTableScrollView.contentView)
yields to the same error
Type 'NSNotification.Name?' has no member 'boundsDidChangeNotification'
So, at this stage I have 2 questions:
- what is the correct notification name ?
- i am not sure this will allow me to finely sync the 2 tableViews vertical scroll. I would do this in the selector:
if notification.object as? NSTableView == dataTableView {
rowHeaderScrollView.contentView.bounds.origin.y = dataScrollView.contentView.bounds.origin.y
} else if notification.object as? NSTableView == rowHeaderTableView {
dataScrollView.contentView.bounds.origin.y = rowHeaderScrollView.contentView.bounds.origin.y
}
Is there a better way ?
Solved.
Just need to use NSView.boundsDidChangeNotification.
For those who may need, the following provides a decent sync (even tyhough some lagging in sync) between the 2 tableViews.
In viewDidLoad, add observers
dataScrollView.contentView.postsBoundsChangedNotifications = true
NotificationCenter.default.addObserver(self, selector: #selector(boundsDidChangeNotification), name: NSView.boundsDidChangeNotification, object: dataScrollView.contentView)
rowHeaderScrollView.contentView.postsBoundsChangedNotifications = true
NotificationCenter.default.addObserver(self, selector: #selector(boundsDidChangeNotification), name: NSView.boundsDidChangeNotification, object: rowHeaderScrollView.contentView)
with the callback:
@objc func boundsDidChangeNotification(_ notification: Notification) {
if notification.object as? NSClipView == dataScrollView.contentView {
rowHeaderScrollView.contentView.bounds.origin.y = dataScrollView.contentView.bounds.origin.y
} else if notification.object as? NSClipView == rowHeaderScrollView.contentView {
dataScrollView.contentView.bounds.origin.y = rowHeaderScrollView.contentView.bounds.origin.y
}
}