5

How can one detect two finger zoom gestures on MacBook trackpad? (within a selected NSView)

hotpaw2
  • 70,107
  • 14
  • 90
  • 153

3 Answers3

5

A simple swift solution:

var zoom:CGFloat = 0
override func magnify(with event: NSEvent) {
    super.magnify(with: event)
    if(event.phase == .changed){
        zoom += event.deltaZ
    }else if(event.phase == .began){
        zoom = 0//reset
    }else if(event.phase == .ended){
        //Swift.print("zoom: " + "\(zoom)")
        var dir:Int
        if(zoom < -100){
            Swift.print("zoom out")
            dir = 1
        }else if(zoom > 100){
            Swift.print("zoom in")
            dir = -1
        }else{
            Swift.print("no zoom")
            dir = 0
        }
    }
}

It detects if a zoom gesture has occurred +-100 deltaZ (Aka Pinch in/out to zoom)

More info and research surrounding this approach:
http://eon.codes/blog/2016/02/10/Gesture-research/

Sentry.co
  • 5,355
  • 43
  • 38
4

There's an event type (NSEventTypeMagnify) for pinch gestures, as well as a NSResponder method (-magnifyWithEvent:) for handling such events. Cocoa differs a bit from Cocoa Touch in this respect; on the desktop, you generally let the OS interpret the gestures for you, and you respond to the meaning of the gesture rather than trying to identify the gesture itself.

Caleb
  • 124,013
  • 19
  • 183
  • 272
4

Updated Swift solution

It looks like the answer from eonist is slightly outdated as deltaZ seems to deprecated (I use macOS 10.13.6 aka High Sierra, Xcode 9.4.1). Solution is for NSScrollView.

override func magnify(with event: NSEvent) {
    if(event.phase == .changed){
        onZoomChanged(magnification: self.magnification * (1 + event.magnification))
    }
}

func onZoomChanged(magnification: CGFloat) {
    allowsMagnification = true
    let centerPos =  documentVisibleRect.midPoint // midPoint is a simple CGRect extension
    setMagnification(magnification, centeredAt: centerPos)
}
Wizard of Kneup
  • 1,863
  • 1
  • 18
  • 35