【问题标题】:iOS : How to detect Shake motion?iOS:如何检测抖动运动?
【发布时间】:2012-04-26 15:38:14
【问题描述】:

我将以下代码添加到我的 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”的方法不会被调用。 我应该怎么做才能在我的应用程序中实现这个功能? 有什么想法吗?

【问题讨论】:

    标签: ios shake


    【解决方案1】:

    这可能会对您有所帮助...
    https://stackoverflow.com/a/2405692/796103

    他说你应该将UIApplicationapplicationSupportsShakeToEdit设置为 YES。并覆盖 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:)

    【讨论】:

    • 哈哈,他从来没有这样做过。
    • 为什么在[super viewWillDisappear:animated]; 之前调用[self resignFirstResponder];?这似乎很奇怪。
    【解决方案2】:

    你可以做这样的事情......

    首先...

    在 App 的 Delegate 中设置 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 方法添加到您的视图控制器:

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

    如果第一个答案没有,那应该可以工作,而且这只是快速输入而不是测试:)

    【讨论】:

      【解决方案3】:

      如果您希望能够检测整个应用程序的抖动运动,最好的方法是使用自定义类覆盖您的应用程序的类。

      然后在您的自定义应用程序类中实现它

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

      【讨论】:

      • 对于那些寻找全局应用内抖动检测代码的人来说,这是最好的答案,而不是绑定到单视图控制器。
      • 为了覆盖你 main.m 中的 UIApplication 把这个:return UIApplicationMain(argc, argv, @"PSApplication", NSStringFromClass([AppDelegate class]));
      • 为什么不直接继承- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
      • 我猜你也可以这样做... :-) 给猫剥皮的方法不止一种。但是如果你的 UIApplication 不是第一响应者,它会起作用吗?
      • 每次摇一摇会有两个发送事件。在模拟器中测试。
      【解决方案4】:

      我扩展了 UIApplication 类并添加了对 main 的类引用: 我的应用程序.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]));
      }
      

      这适用于所有情况。

      【讨论】:

      • 不错的解决方案!干杯
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-02
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      • 1970-01-01
      相关资源
      最近更新 更多