У меня есть NSScrollView, и мне нужно масштабировать DocumentView с помощью мыши (вертикальное движение) вокруг точки фокусировки (точка внутри documentView). Я использовал NSScrollView - (void)setMagnification:(CGFloat)magnification centeredAtPoint:(NSPoint)point
. Увеличение вычисляется с помощью дельты Y движения мыши на дорожке mouseDown l oop, point
- местоположение мыши внутри DocumentView на mouseDown:
. Хотя масштабирование назад и вперед (с тем же point
) вызывает смещение источника documentView, поэтому, когда я возвращаюсь к той же точке с помощью мыши (точка, где я начал масштабировать), фактические пиксели под курсором мыши перемещаются. Это выглядит как ошибка в вычислении contentView.bounds.origin для NSScrollView во время вызова - (void)setMagnification:(CGFloat)magnification centeredAtPoint:(NSPoint)point
. Кто-нибудь заметил / исправил это?
Код, используемый для увеличения NSScroll documentView с вертикальным движением мыши:
@interface MyViewController ()
{
CGPoint focusPoint;
CGPoint startMouseLocation;
CGFloat startZoom;
}
@property (weak) IBOutlet NSScrollView *scrollView;
@property (weak) IBOutlet OverlayView *overlay;
@end
@implementation MyViewController
- (void)awakeFromNib
{
[super awakeFromNib];
NSImage* image = [NSImage imageNamed: @"your_image_name"];
self.scrollView.documentView.wantsLayer = YES;
self.scrollView.documentView.layer.contents = image;
[self.scrollView.documentView setFrameSize: image.size];
}
- (void)mouseDown:(NSEvent *)event
{
self.overlay.testPoint = CGPointIntegral([self.overlay convertPoint: event.locationInWindow fromView: nil]);
focusPoint = CGPointIntegral([self.scrollView.documentView convertPoint: event.locationInWindow fromView: nil]);
startMouseLocation = CGPointIntegral(event.locationInWindow);
startZoom = self.scrollView.magnification;
[self.scrollView setMagnification: startZoom centeredAtPoint: focusPoint];
BOOL keepOn = YES;
NSPoint mouseLoc;
while (keepOn) {
event = [self.view.window nextEventMatchingMask: NSEventMaskLeftMouseUp | NSEventMaskLeftMouseDragged];
mouseLoc = event.locationInWindow;
switch (event.type) {
case NSEventTypeLeftMouseDragged:
{
NSInteger y = CGPointIntegral(mouseLoc).y;
CGFloat deltaY = y - startMouseLocation.y;
CGFloat zoom = startZoom + deltaY/100.0;
[self.scrollView setMagnification: zoom centeredAtPoint: focusPoint];
}
break;
case NSEventTypeLeftMouseUp:
keepOn = NO;
break;
default:
break;
}
};
return;
}
@end
Добавить 2: да, я пытался установить точку фокусировки в пространстве documentView или contentView, но это не влияет на дрейфует во время зума. Проверьте это видео: https://www.dropbox.com/s/zkpg2p53l84s55c/m.mov?dl=0 Оранжевая точка - это место фокусировки. После увеличения и уменьшения масштаба изображение сместилось влево. Дельта (расстояние изображения от точки фокусировки) меньше, когда точка фокусировки ближе к центру изображения. Я проверил все вычисления zoom и focusPoint, и, кажется, все в порядке. После нескольких циклов увеличения / уменьшения я попытался поместить курсор мыши в точное положение при начале масштабирования (focusPoint), чтобы получить исходное значение масштабирования, и даже focusPoint и масштабирование, переданные методу setMagnification:centeredAtPoint:
, были правильными (равными значения при запуске масштабирования), изображение сместилось.