Search code examples
objective-cxcodemacosmulti-touchgesture

Detect multi-touch gestures or drags with mouse in Mac OS X App


How can one detect when a drag is happening or a swipe on the track-pad or magic-mouse is occurring in a Mac OSX app being made in Xcode.

By drag I mean the user has clicked on the left or right edge of the window and the mouse is held down and now moving away from that side-of-the-window horizontally.

I am trying to run code on left drag or right swipe (on magic-mouse or track-pad) and another set of code on right drag or left swipe (on magic-mouse or track-pad).

Here are some definitions of the gestures that I am talking about:

A left drag is when the right side of the window is clicked and held on and the cursor moves to the left.

A right drag is when the left side of the window is clicked and held on and the cursor moves to the right.

A top drag is when the top on the window, under the frame / where the traffic-lights are, is being dragged down.

A top swipe is a swipe that starts on the top of the track-pad or magic-mouse and goes down.

In pseudo-code what I am trying to achieve is like:

if( right-drag || left-swipe ){
    /*run code*/
}
else if( left-drag || right-swipe ){
    /* run different code */
}
else if( top-drag || top-swipe ){
    /* run other code */
}
else{
   /* do nothing */
}

Solution

  • Cocoa Event Handling Guide is the place to start

    Especially the part on Handling Gesture Events.

    They tell you how to deal with:

    • Pinching movements (in or out) are gestures meaning zoom out or zoom in (also called magnification).
    • Two fingers moving in opposite semicircles is a gesture meaning rotate.
    • Three fingers brushing across the trackpad surface in a common direction is a swipe gesture.
    • Two fingers moving vertically or horizontally is a scroll gesture.

    and more...

    In particular the method:

    - (void)swipeWithEvent:(NSEvent *)event
    

    from NSResponder is your best bet. T*his event informs the receiver that the user has begun a swipe gesture. The event will be sent to the view under the touch in the key window.*


    Taken from the same document, below is an example on how to Handle s swipe gesture:

    - (void)swipeWithEvent:(NSEvent *)event {
        CGFloat x = [event deltaX];
        CGFloat y = [event deltaY];
        if (x != 0) {
            swipeColorValue = (x > 0)  ? SwipeLeftGreen : SwipeRightBlue;
        }
        if (y != 0) {
            swipeColorValue = (y > 0)  ? SwipeUpRed : SwipeDownYellow;
        }
        NSString *direction;
        switch (swipeColorValue) {
            case SwipeLeftGreen:
                direction = @"left";
                break;
            case SwipeRightBlue:
                direction = @"right";
                break;
            case SwipeUpRed:
                direction = @"up";
                break;
            case SwipeDownYellow:
            default:
                direction = @"down";
                break;
        }
        [resultsField setStringValue:[NSString stringWithFormat:@"Swipe %@", direction]];
        [self setNeedsDisplay:YES];
    }