Как определить, когда кто-то трясет iPhone? - PullRequest
338 голосов
/ 30 сентября 2008

Я хочу реагировать, когда кто-то трясет iPhone. Меня не особо волнует, как они его трясут, просто то, что его энергично размахивали на долю секунды. Кто-нибудь знает, как это обнаружить?

Ответы [ 16 ]

5 голосов
/ 13 марта 2015

Во-первых, я знаю, что это старый пост, но он все еще актуален, и я обнаружил, что два ответа с наибольшим количеством голосов не обнаружили дрожание как можно раньше . Вот как это сделать:

  1. Свяжите CoreMotion с вашим проектом на этапах сборки цели: CoreMotion
  2. В вашем ViewController:

    - (BOOL)canBecomeFirstResponder {
        return YES;
    }
    
    - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
    {
        if (motion == UIEventSubtypeMotionShake) {
            // Shake detected.
        }
    }
    
5 голосов
/ 18 августа 2009

Извините, что опубликовал это как ответ, а не как комментарий, но, как вы можете видеть, я новичок в Stack Overflow, и поэтому я еще не достаточно авторитетен, чтобы оставлять комментарии!

В любом случае, я второй @cire, чтобы убедиться, что установил статус первого респондента, как только представление является частью иерархии представлений. Так, например, установка статуса первого респондента в вашем контроллере вида viewDidLoad не будет работать. И если вы не уверены, работает ли он, [view becomeFirstResponder] возвращает вам логическое значение, которое вы можете проверить.

Еще один момент: вы можете использовать контроллер представления для захвата события встряхивания, если вы не хотите без необходимости создавать подкласс UIView. Я знаю, что это не так уж много хлопот, но все же есть возможность. Просто переместите фрагменты кода, которые Кендалл поместил в подкласс UIView, в свой контроллер и отправьте сообщения becomeFirstResponder и resignFirstResponder на self вместо подкласса UIView.

4 голосов
/ 12 июля 2014

Самое простое решение - получить новое корневое окно для вашего приложения:

@implementation OMGWindow : UIWindow

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
    if (event.type == UIEventTypeMotion && motion == UIEventSubtypeMotionShake) {
        // via notification or something   
    }
}
@end

Тогда в вашем приложении делегат:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.window = [[OMGWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    //…
}

Если вы используете раскадровку, это может быть сложнее, я не знаю точно, какой код вам понадобится в делегате приложения.

1 голос
/ 10 сентября 2017

Версия Swiftease, основанная на самом первом ответе!

override func motionEnded(_ motion: UIEventSubtype, with event: UIEvent?) {
    if ( event?.subtype == .motionShake )
    {
        print("stop shaking me!")
    }
}
1 голос
/ 21 февраля 2013

Просто используйте эти три метода, чтобы сделать это

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event{
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event{

для получения более подробной информации вы можете проверить полный пример кода над там

0 голосов
/ 15 сентября 2017

Чтобы включить это приложение, я создал категорию в UIWindow:

@implementation UIWindow (Utils)

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if (motion == UIEventSubtypeMotionShake) {
        // Do whatever you want here...
    }
}

@end
...