如何在底部滚动时检测位置滚动?
[[_scrollView contentView] setPostsBoundsChangedNotifications:YES];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(boundsDidChangeNotification:)
name:NSViewBoundsDidChangeNotification
object:[_scrollView contentView]];
- (void) boundsDidChangeNotification: (NSNotification *) notification
{
NSPoint currentScrollPosition = [[_scrollView contentView] bounds].origin;
}
更新: 我原来的答案是完全错误的。 感谢JWWalker和Wil Shipley通过评论让我意识到这一点。
对于通过搜索来到这里的人来说,这是一个更有帮助的答案:
与UIScrollView
不同,NSScrollView
不提供委托方法,以便在视图滚动到顶部/底部时通知您。
要检测这些情况,您必须启用boundsDidChange
通知并订阅它们。
接收边界更新时,可以检查剪辑视图边界的y
坐标是否为0
(= bottom),或者剪辑视图边界的上边缘是否与文档视图(= top)对齐。
private func configureScrollView() {
self.scrollView.contentView.postsBoundsChangedNotifications = true
NotificationCenter.default.addObserver(self, selector: #selector(contentViewDidChangeBounds), name: NSView.boundsDidChangeNotification, object: self.scrollView.contentView)
}
@objc
func contentViewDidChangeBounds(_ notification: Notification) {
guard let documentView = scrollView.documentView else { return }
let clipView = scrollView.contentView
if clipView.bounds.origin.y == 0 {
print("bottom")
} else if clipView.bounds.origin.y + clipView.bounds.height == documentView.bounds.height {
print("top")
}
}
对于使用弹性滚动的滚动视图,更新会有一个短暂的延迟,因为剪辑视图似乎推迟了边界更改通知,直到滚动弹跳结束。
您可以使用NSScrollView
的contentView的可见矩形而不是边界:
- (void)boundsDidChangeNotification:(NSNotification*) notification
{
NSRect visibleRect = [[_scrollView contentView] documentVisibleRect];
NSLog(@"Visible rect:%@", NSStringFromRect(visibleRect));
NSPoint currentScrollPosition = visibleRect.origin;
}
内容视图边界在滚动期间不会更改,因此在原始代码中,bounds.origin可能始终返回0/0。
if (_scrollView.verticalScroller.floatValue > 0.9)
{
// bottom
// do something
}
如果要在滚动结束后检测到。当视图滚动时,@ thomas的答案被检测到
NotificationCenter.default.addObserver(
self,
selector: #selector(scrollViewDidScroll),
name:NSScrollView.didLiveScrollNotification,
object: scrollView
)
@objc func scrollViewDidScroll (notification: NSNotification) {
guard let documentView = scrollView.documentView else { return }
let clipView = scrollView.contentView
if clipView.bounds.origin.y == 0 {
print("top")
} else if clipView.bounds.origin.y + clipView.bounds.height == documentView.bounds.height {
print("bottom")
}
}