Как анимировать увеличение и уменьшение масштаба в NSScrollView, чтобы оно было плавным? - PullRequest
0 голосов
/ 27 мая 2020

Ниже приведены функции, которые я использую для установки нового размера представлений прокрутки documentView, однако я не могу понять, как совместить изменение размера кадра с изменением положения прокрутки. Если я применяю анимацию к вещам в том виде, в каком они есть, размер изменяется, и изображение перемещается относительно нижнего левого угла, а затем изображение возвращается на место. Как объединить анимацию таким образом, чтобы изменение размера и положение прокрутки менялись вместе - или любой другой способ добиться плавного увеличения / уменьшения масштаба.

func zoomIn(zoomFactor: CGFloat = zoomFactor){

        guard let docView = self.docView, let scrollView = self.scrollView else {
            return
        }

        let visible = scrollView.documentVisibleRect
        let newrect = NSInsetRect(visible, NSWidth(visible)*(1 - 1/zoomFactor)/2.0, NSHeight(visible)*(1 - 1/zoomFactor)/2.0);
        let frame = docView.frame

        self.execZoom(docView: docView,
                      size:CGSize(width: zoomFactor, height: zoomFactor),
                      frame:CGRect(x: 0, y: 0, width: frame.size.width * zoomFactor, height: frame.size.height * zoomFactor),
                      origin:newrect.origin)

    }
    func zoomOut(zoomFactor: CGFloat = zoomFactor){
        guard let docView = self.docView, let scrollView = self.scrollView else {
            return
        }
        let visible = scrollView.documentVisibleRect
        let newrect = NSOffsetRect(visible, -NSWidth(visible)*(zoomFactor - 1)/2.0, -NSHeight(visible)*(zoomFactor - 1)/2.0)

        let frame = docView.frame

        self.execZoom(docView: docView,
                      size: CGSize(width: 1/zoomFactor, height: 1/zoomFactor),
                      frame: CGRect(x: 0, y: 0, width: frame.size.width / zoomFactor, height: frame.size.height / zoomFactor),
                      origin: newrect.origin)
    }
    func execZoom(docView: NSView, size: CGSize, frame: CGRect, origin: CGPoint){

            docView.scaleUnitSquare(to: size)

            docView.frame = frame

            docView.scroll(origin)

    }

Ответы [ 2 ]

0 голосов
/ 17 июня 2020

Есть простой способ использовать generi c 'animated'.

Из документации: Чтобы анимировать увеличение, используйте аниматор объекта. Значение по умолчанию - 1.0. (https://developer.apple.com/documentation/appkit/nsscrollview/1403497-magnification?language=objc)

Что это означает «использовать аниматор объекта»?

Вместо:

self.scrollView.setMagnification(magnification, centeredAt: point)

Вызов аниматора:

self.scrollView.animator().setMagnification(magnification, centeredAt: point)
0 голосов
/ 27 мая 2020

Хорошо, просто выбросьте все это и сделайте это ... безумно быстро, плавно и все лежащие в основе CALayers с изображениями и перетаскиваемыми CALayers, которые визуализируются с помощью собственных методов draw (), похоже, масштабируются в векторном формате - без пикселизации шрифтов, линии или изображения.

   override func scrollWheel(with event: NSEvent) {

        guard event.modifierFlags.contains(.option) else {
            super.scrollWheel(with: event)
            return
        }

        let dy = event.deltaY
        if dy != 0.0 {

            let magnification = self.scrollView.magnification + dy/30
            let point = self.scrollView.contentView.convert(event.locationInWindow, from: nil)

            self.scrollView.setMagnification(magnification, centeredAt: point)
        }
    }
...