web-dev-qa-db-ja.com

iOS:シェイクモーションを検出する方法は?

次のコードをappDelegate.mに追加しました

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

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if (motion == UIEventSubtypeMotionShake )
    {
        // User was shaking the device. Post a notification named "shake".
        [[NSNotificationCenter defaultCenter] postNotificationName:@"shake" object:self];
    }
}

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

- (void)shakeSuccess
{
    // do something...
}

そして私は追加しました:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    // INIT THE BACKGROUND PATH STRING

    [self refreshFields];
    [self.window addSubview:navController.view];
    [self.window makeKeyAndVisible];
    ***[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(shakeSuccess) name:@"shake" object:nil];***

    return YES;
}

IPhoneでアプリを起動すると、「shakeSuccess」という名前のメソッドが呼び出されません。この機能をアプリに実装するにはどうすればよいですか?何か案が?

24
Samblg

これはあなたを助けるかもしれません...
https://stackoverflow.com/a/2405692/7961

UIApplicationapplicationSupportsShakeToEditYESに設定する必要があると彼は言います。 VCの3つのメソッドをオーバーライドします。

-(BOOL)canBecomeFirstResponder {
    return YES;
}

-(void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self becomeFirstResponder];
}

- (void)viewWillDisappear:(BOOL)animated {
    [self resignFirstResponder];
    [super viewWillDisappear:animated];
}

コードの残りの部分は問題ありません。 (-motionEnded:withEvent:

59

あなたはこのようなことをすることができます...

まず...

アプリのデリゲートでapplicationSupportsShakeToEditプロパティを設定します:

- (void)applicationDidFinishLaunching:(UIApplication *)application {

    application.applicationSupportsShakeToEdit = YES;

    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}

第二に...

ビューコントローラのcanBecomeFirstResponder、viewDidAppear:、viewWillDisappear:メソッドを追加/オーバーライド:

-(BOOL)canBecomeFirstResponder {
    return YES;
}

-(void)viewDidAppear:(BOOL)animated {
   [super viewDidAppear:animated];
   [self becomeFirstResponder];
}

- (void)viewWillDisappear:(BOOL)animated {
    [self resignFirstResponder];
    [super viewWillDisappear:animated];
 }

第三に...

motionEndedメソッドをView Controllerに追加します:

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
   if (motion == UIEventSubtypeMotionShake)
   {
    // your code
   }
 }

最初の答えがうまくいかず、これがテストされずにすばやくタイプされた場合、それはうまくいくはずです:)

26
Thomas Stone

アプリ全体のシェイクモーションを検出できるようにする場合、最良の方法は、アプリケーションのクラスをカスタムクラスでオーバーライドすることです。

次に、これをカスタムアプリケーションクラスに実装します。

@implementation PSApplication

- (void)sendEvent:(UIEvent *)event
{
    if ( event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake ) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"shakeNotification" object:nil];
    }

    [super sendEvent:event];
}

@end
14
Cherpak Evgeny

UIApplicationクラスを拡張し、クラス参照をメインに追加しました:MyApplication.h

@interface MyApplication : UIApplication

@end

MyApplication.m

@implementation MyApplication

- (void) sendEvent:(UIEvent *)event
{
    if( event && (event.subtype==UIEventSubtypeMotionShake))
    {
        AppDelegate *objAppDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

        [objAppDelegate doWhatEver];
        [super sendEvent:event];
    }
    else
    {
        [super sendEvent:event];
    }
}

@end

そしてmain.mの最後のステップ

int main(int argc, char *argv[])
{
return UIApplicationMain(argc, argv, NSStringFromClass([MyApplication class]), NSStringFromClass([AppDelegate class]));
}

これはすべてのケースで機能します。

3
Harit K