Gesture recognition in Apple Watch (WatchKit)

2020-02-12 08:25发布

问题:

I'm looking for how to detect gestures in an Apple Watch app, via the WatchKit SDK. In iOS we can use some code like this:

- (void)viewDidLoad
{
    ...
    UISwipeGestureRecognizer *swipeRightBlack = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(slideToRightWithGestureRecognizer:)];
    swipeRightBlack.direction = UISwipeGestureRecognizerDirectionRight;
    [self.viewBlack addGestureRecognizer:swipeRightBlack];
}

...but this doesn't work in the Apple Watch simulator. Is there a way to override the default gesture actions using WatchKit, or just recognize them when the OS receives them?

回答1:

watchOS 3 adds third-party support for WKGestureRecognizer.

Apple has also updated their WatchKit Catalog sample code to include a WKInterfaceController gesture example demonstrating how to use various gestures on the Apple Watch.

Here's a snippet from their code showing two of the actions for gestures configured in Storyboard:

class GestureDetailController : WKInterfaceController {
    @IBOutlet var tapGroup: WKInterfaceGroup!
    @IBOutlet var panGroup: WKInterfaceGroup!

    ...

    @IBAction func tapRecognized(_ sender: AnyObject) {
        tapGroup.setBackgroundColor(UIColor.green())
        scheduleReset()
    }

    @IBAction func panRecognized(_ sender: AnyObject) {
        if let panGesture = sender as? WKPanGestureRecognizer {
            panGroup.setBackgroundColor(UIColor.green())
            panLabel.setText("offset: \(NSStringFromCGPoint(panGesture.translationInObject()))")
            scheduleReset()
        }
    }


回答2:

Wonder how this is achieved: in Apple's demo video, the group in the row is swiped left and the buttons below are revealed.



回答3:

As far as I can tell, there is no way to do it. Whole Apple Watch is super limited when it comes to what can you do with it. I suppose that kind of makes sense since it should be just peripheral to your main app but it's a bit too limited for my liking.



回答4:

Do you read the iWatch Guide? Apples say´s:

Gestures: The system handles all gestures on your behalf, using them to implement standard behaviors:

  • Vertical swipes scroll the current screen.
  • Horizontal swipes display the previous or next page in a page-based interface.
  • Left edge swipes navigate back to the parent interface controller.
  • Taps indicate selection or interaction. Taps are handled by the system and reported to your WatchKit extension’s action methods.

Apple Watch does not support multi-finger gestures such as pinches.

...taken from Apple iWatch Human Interface Guidelines. So i don´t think this "hack" give you the same behavior as in iOS.



回答5:

Apple automatically provides to the user swipe gestures to navigate forward and back through your controllers, and to scroll the views the Watch has laid out. All of this is done without requiring any code or gesture configuration by the third party developer. All we have ability to do is define the segues and layout of the objects in Interface Builder and the OS takes care of the rest.

There is no direct access to swipes or other gestures or tap locations in WatchKit at present, and there is no reason to believe that is going to change before the release of the Watch.

It is unclear whether Apple may be willing to enable this in the future, or whether they will never open this up to developers, but they are encouraging developers to submit enhancement requests via their bug reporter. Be sure to describe your desired use case and the problem you're trying to solve, as well as what your proposed solution is, as there may be a different facility they can provide that will solve your problem case even if it does so in a different way than we expect.



回答6:

You can't do it yet. The alternative option right now would be to use buttons inside the screen to perform your swipe action.



回答7:

Im using Xcode 7.2 currently coding for watchos2, for my app I only want the button to perform a method when they double tap within .5 seconds, if users only single tap then it won't perform the action. For example:

In my .h

#import <WatchKit/WatchKit.h>
#import <Foundation/Foundation.h>

@interface InterfaceController : WKInterfaceController

- (IBAction)btnActivate;
@property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceButton *activateBtn;

@end

At the top of my .m file I declared:

    int taps = 1;

- (IBAction)btnActivate {

            taps = taps + 1;

            if (taps == 2){
                [activateBtn setBackgroundColor:[UIColor grayColor]];
                [self performSelector:@selector(tapOne:) withObject:self afterDelay:0.5];

            }
            else if (taps == 3){
                [self performSelector:@selector(tapTwo:) withObject:self afterDelay:0];
                [activateBtn setEnabled:NO];
                [activateBtn setBackgroundColor:[UIColor redColor]];

            } else {
               //Do other things here if you want 
            }
        }
- (void) tapOne: (id) sender{

            if (taps == 2){

                 [self performSelector:@selector(afterTapDone:) withObject:self afterDelay:1];
            } else {

            }

        }


- (void) tapTwo: (id) sender {

        //Perform button actions here when user double taps 

            [self performSelector:@selector(afterTapDone:) withObject:self afterDelay:10];


        }

- (void) afterTapDone: (id) sender {
            taps = 1;
            [activateBtn setEnabled:YES];
            [activateBtn setBackgroundColor:[UIColor colorWithRed:0/255.0f green:174/255.0f blue:239/255.0f alpha:1.0f]];
            [activateBtn setTitle:@"Activate"];

        }

Of course you can tweak the afterDelays etc, and clean the code up but this is how I was able to get double taps working