I'm making a Mac app which needs to know when the user is scrolling the NSScrollView
, however, I can't find any methods like UIScrollView
, which has the following delegate methods:
– scrollViewDidScroll:
– scrollViewWillBeginDragging:
– scrollViewDidEndDragging:willDecelerate:
– scrollViewShouldScrollToTop:
– scrollViewDidScrollToTop:
– scrollViewWillBeginDecelerating:
– scrollViewDidEndDecelerating:
Can I have the similar delegate methods for the App Kit? Thanks in advance.
Kai.
You can monitor a scroll view's changes by monitoring the bounds of it's content view. First set the content view to post its changes with
[contentView setPostsBoundsChangedNotifications:YES];
Then register as an observer of those notifications with
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(boundsDidChange:) name:NSViewBoundsDidChangeNotification object:contentView];
Had the same problem recently... To somewhat emulate deceleration callbacks it is possible to override
-(void) scrollWheel:(NSEvent *)theEvent
of NSScrollView class, but then check theEvent.momentumPhase instead of theEvent.phase for event phases.
Adding to @Sean Rich answer.
The contentView
is the NSClipView
between the NSScrollView
and NSCollectionView
.
For this to work, both the ClipView
needs to be set to postsBoundsChangedNotifications
and should be passed in the notification object.
self.clipView.postsBoundsChangedNotifications = true
NotificationCenter.default.addObserver(self,
selector: #selector(collectionViewDidScroll(notification:)),
name: NSView.boundsDidChangeNotification,
object: self.clipView)
Update for Swift 4:
scrollView.contentView.postsBoundsChangedNotifications
Also the call is:
NotificationCenter.default.addObserver(self,
selector: #selector(boundsChange),
name: NSView.boundsDidChangeNotification,
object: scrollView.contentView)
Edit: the collection in mac doesn't inherit from scrollview. updated properly
my two cents for swift 4.2 OSX:
....
if let clipView = self.collectionView.superview, let sv = clipView.superview as? NSScrollView{
let contentView = sv.contentView
contentView.postsBoundsChangedNotifications = true
NotificationCenter.default.addObserver(self,
selector: #selector(collectionViewDidScroll(notification:)),
name: NSView.boundsDidChangeNotification,
object: clipView)
}
//MARK: scrollview observer:
@objc func collectionViewDidScroll(notification: Notification){
}