У меня есть два экземпляра NSScrollView, которые представляют один и тот же контент. Второе представление прокрутки, однако, имеет уменьшенную версию представления документа, представленного в первом представлении прокрутки. И ширина, и высота могут быть индивидуально масштабированы, а исходные ограничения ширины и высоты могут быть потеряны, но это не имеет значения.
У меня работает синхронизированная прокрутка, даже принимая во внимание, что второе представление прокрутки должно настроить свое поведение прокрутки на основе масштабирования. Есть одна маленькая загвоздка, из которой я вырывал свои волосы:
- Поскольку оба вида успешно прокручиваются по меньшему виду, необходимо медленно догонять более крупный вид, чтобы они оба "достигли" конца своего документа одновременно. Сейчас этого не происходит, и в результате меньший вид находится в конце документа перед большим.
Код для синхронизированной прокрутки основан на примере из документации Apple под названием «Синхронизация представлений прокрутки». Я адаптировал synchronizedViewContentBoundsDidChange:
к следующему коду:
- (void) synchronizedViewContentBoundsDidChange: (NSNotification *) notification {
// get the changed content view from the notification
NSClipView *changedContentView = [notification object];
// get the origin of the NSClipView of the scroll view that
// we're watching
NSPoint changedBoundsOrigin = [changedContentView documentVisibleRect].origin;;
// get our current origin
NSPoint curOffset = [[self contentView] bounds].origin;
NSPoint newOffset = curOffset;
// scrolling is synchronized in the horizontal plane
// so only modify the x component of the offset
// "scale" variable will correct for difference in size between views
NSSize ownSize = [[self documentView] frame].size;
NSSize otherSize = [[[self synchronizedScrollView] documentView] frame].size;
float scale = otherSize.width / ownSize.width;
newOffset.x = floor(changedBoundsOrigin.x / scale);
// if our synced position is different from our current
// position, reposition our content view
if (!NSEqualPoints(curOffset, changedBoundsOrigin)) {
// note that a scroll view watching this one will
// get notified here
[[self contentView] scrollToPoint:newOffset];
// we have to tell the NSScrollView to update its
// scrollers
[self reflectScrolledClipView:[self contentView]];
}
}
Как мне нужно изменить этот код, чтобы достичь требуемого эффекта (обе полосы прокрутки, приходящие в конце документа)?
РЕДАКТИРОВАТЬ: Некоторое пояснение, поскольку это приводило в замешательство, когда я сам читал его обратно: меньший вид должен замедляться, когда прокрутка первого вида достигает конца. Это, вероятно, будет означать переоценку этого коэффициента масштабирования ... но как?
РЕДАКТИРОВАТЬ 2: я изменил метод на основе предложения Алекса:
NSScroller *myScroll = [self horizontalScroller];
NSScroller *otherScroll = [[self synchronizedScrollView] horizontalScroller];
//[otherScroll setFloatValue: [myScroll floatValue]];
NSLog(@"My scroller value: %f", [myScroll floatValue]);
NSLog(@"Other scroller value: %f", [otherScroll floatValue]);
// Get the changed content view from the notification.
NSClipView *changedContentView = [notification object];
// Get the origin of the NSClipView of the scroll view that we're watching.
NSPoint changedBoundsOrigin = [changedContentView documentVisibleRect].origin;;
// Get our current origin.
NSPoint curOffset = [[self contentView] bounds].origin;
NSPoint newOffset = curOffset;
// Scrolling is synchronized in the horizontal plane so only modify the x component of the offset.
NSSize ownSize = [[self documentView] frame].size;
newOffset.x = floor(ownSize.width * [otherScroll floatValue]);
// If our synced position is different from our current position, reposition our content view.
if (!NSEqualPoints(curOffset, changedBoundsOrigin)) {
// Note that a scroll view watching this one will get notified here.
[[self contentView] scrollToPoint: newOffset];
// We have to tell the NSScrollView to update its scrollers.
[self reflectScrolledClipView:[self contentView]];
}
При использовании этого метода меньший вид «обгоняется» большим, когда оба скроллера достигают значения 0,7, что нехорошо. Затем увеличенное изображение прокручивается за его конец документа.