我有一个相当类似的问题。 我有3个滚动视图进行同步。 一个只是水平滚动的标题。 一个是只能垂直滚动的侧栏。 其中一个是标题下方的内容区域,并位于侧边栏的右侧。 标题和边栏应随内容区域一起移动。 如果滚动,内容区域应该随标题或侧栏一起移动。
水平滚动从来都不是问题。 垂直滚动总是导致两个视图滚动到相反的方向。
奇怪的解决方案我来创建一个clipView子类(我已经做了,因为你几乎总是需要如果你想要什么好东西,不会出来的盒子。) 在clipView子类,我添加一个属性BOOL isInverted并在重载isFlipped我返回self.isInverted。
奇怪的是,这些用于翻转的BOOL值是从一开始就在所有3个视图中设置和匹配的。 看来,滚动机械确实是越野车。 我偶然发现的解决方法是在调用之间夹入滚动同步代码以将侧栏和内容视图设置为未翻转,然后更新任何垂直滚动,然后再次设置翻转。 必须在滚动机械试图支持倒滚动一些老代码...
这些是由NSNotificationCenter的addObserver方法称为观察NSViewBoundsDidChangeNotification为clipViews方法。
- (void)synchWithVerticalControlClipView:(NSNotification *)aNotification
{
NSPoint mouseInWindow = self.view.window.currentEvent.locationInWindow;
NSPoint converted = [self.verticalControl.enclosingScrollView convertPoint:mouseInWindow fromView:nil];
if (!NSPointInRect(converted, self.verticalControl.enclosingScrollView.bounds)) {
return;
}
[self.contentGridClipView setIsInverted:NO];
[self.verticalControlClipView setIsInverted:NO];
// ONLY update the contentGrid view.
NSLog(@"%@", NSStringFromSelector(_cmd));
NSPoint changedBoundsOrigin = self.verticalControlClipView.documentVisibleRect.origin;
NSPoint currentOffset = self.contentGridClipView.bounds.origin;
NSPoint newOffset = currentOffset;
newOffset.y = changedBoundsOrigin.y;
NSLog(@"\n changedBoundsOrigin=%@\n currentOffset=%@\n newOffset=%@", NSStringFromPoint(changedBoundsOrigin), NSStringFromPoint(currentOffset), NSStringFromPoint(newOffset));
[self.contentGridClipView scrollToPoint:newOffset];
[self.contentGridClipView.enclosingScrollView reflectScrolledClipView:self.contentGridClipView];
[self.contentGridClipView setIsInverted:YES];
[self.verticalControlClipView setIsInverted:YES];
}
- (void)synchWithContentGridClipView:(NSNotification *)aNotification
{
NSPoint mouseInWindow = self.view.window.currentEvent.locationInWindow;
NSPoint converted = [self.contentGridView.enclosingScrollView convertPoint:mouseInWindow fromView:nil];
if (!NSPointInRect(converted, self.contentGridView.enclosingScrollView.bounds)) {
return;
}
[self.contentGridClipView setIsInverted:NO];
[self.verticalControlClipView setIsInverted:NO];
// Update BOTH the control views.
NSLog(@"%@", NSStringFromSelector(_cmd));
NSPoint changedBoundsOrigin = self.contentGridClipView.documentVisibleRect.origin;
NSPoint currentHOffset = self.horizontalControlClipView.documentVisibleRect.origin;
NSPoint currentVOffset = self.verticalControlClipView.documentVisibleRect.origin;
NSPoint newHOffset, newVOffset;
newHOffset = currentHOffset;
newVOffset = currentVOffset;
newHOffset.x = changedBoundsOrigin.x;
newVOffset.y = changedBoundsOrigin.y;
[self.horizontalControlClipView scrollToPoint:newHOffset];
[self.verticalControlClipView scrollToPoint:newVOffset];
[self.horizontalControlClipView.enclosingScrollView reflectScrolledClipView:self.horizontalControlClipView];
[self.verticalControlClipView.enclosingScrollView reflectScrolledClipView:self.verticalControlClipView];
[self.contentGridClipView setIsInverted:YES];
[self.verticalControlClipView setIsInverted:YES];
}
这工作99%的时间,只有偶尔的抖动。 水平滚动同步没有问题。
伟大的解决方案! – mohacs
谢谢你,我遇到了一个类似的问题,我试图隐藏叠加滚动条,但它会打破滚动视图中的双指手势滚动。使用这个方法而不是'[scrollView setHasVerticalScroller:NO]'实现了希望隐藏滚动条的结果,但让scrollView仍然正确滚动。 – Andrew