在下一个动作之前,加速度计必须在给定的时间间隔内处于特定方向 [英] Accelerometer must be in a specific orientation for a given time interval before next action

查看:58
本文介绍了在下一个动作之前,加速度计必须在给定的时间间隔内处于特定方向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的应用程序中执行一个方法,但前提是手机在给定的时间间隔内处于正确的加速度计方向.我遇到的问题是每次更新加速度计时,计时器都会重置.我一直无法弄清楚如何触发时间只启动一次,而不是每次更新加速度计时.

I am trying to execute a method in my application, but only after the phone was been in the correct accelerometer orientation for a given time interval. The problem I am having is each time the accelerometer is updated, the timer resets. I have not been able to figure out how to trigger the time to start only once and not each time the accelerometer is updated.

//在 ViewController.h 中

// In ViewController.h

#import <UIKit/UIKit.h>
#import <CoreMotion/CoreMotion.h>

@interface ViewController : UIViewController
{
    float timeTest;
}

@property (nonatomic, strong) CMMotionManager *motionManager;
@property (nonatomic, strong) NSTimer *timerObject;

- (void) testMethod;

- (void) addTime;

- (void) startTimer;

@end

//在 ViewController.m 中

// In ViewController.m

#import "ViewController.h"

@implementation ViewController

@synthesize motionManager;
@synthesize timerObject;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.motionManager = [[CMMotionManager alloc]init];
    [self testMethod];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void) testMethod
{
    if ([self.motionManager isAccelerometerAvailable])
    {
        NSOperationQueue *queue = [[NSOperationQueue alloc]init];
        [self.motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData *accelerometerData,NSError *error)
         {
             if (ABS(accelerometerData.acceleration.x) < 0.30 && ABS(accelerometerData.acceleration.y) < 0.30 && ABS(accelerometerData.acceleration.z) > 0.70) // Phone is flat and screen faces up
             {
                 NSLog(@"Correct position.");  
                 [self startTimer]; // Problem here.  This just continually resets the timer for each accelerometer update.
             }
             else
             {
                 NSLog(@"Incorrect position.");
                 [timerObject invalidate];
                 timeTest = 0.0;
            }

         }];
    }
    else
    {
        NSLog(@"Accelerometer is not available.");
    }
}


- (void) addTime
{
    timeTest = timeTest + 0.1;
    if (timeTest == 3.0)
    {
        [timerObject invalidate];

        // Where code for next action would go.  For feedback, just simply set the screen to green.
        self.view.backgroundColor = [UIColor greenColor];
    }
}

- (void) startTimer
{
    timeTest = 0.0;
    timerObject = [NSTimer scheduledTimerWithTimeInterval:0.1f target:self selector:@selector(addTime) userInfo:nil repeats:YES];
}

@end

任何帮助都会很棒!

推荐答案

一种方法是插入一个 BOOL 标志来指示计时器已启动,以防止它不断被不必要地重新启动.当计时器失效时,您将重置该标志.所以你会有这样的东西(没有经过测试,但我相信你会明白要点):

One way would be to insert a BOOL flag to indicate the timer has started, to prevent it constantly being unnecessarily re-started. You'd then reset the flag when the timer is invalidated. So you'd have something like this (not tested but I'm sure you'll get the gist):

- (void) testMethod
{
    BOOL timerStarted = NO;
    if ([self.motionManager isAccelerometerAvailable])
    {
        NSOperationQueue *queue = [[NSOperationQueue alloc]init];
        [self.motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData *accelerometerData,NSError *error)
         {
             if (ABS(accelerometerData.acceleration.x) < 0.30 && ABS(accelerometerData.acceleration.y) < 0.30 && ABS(accelerometerData.acceleration.z) > 0.70) // Phone is flat and screen faces up
             {
                 NSLog(@"Correct position."); 
                 if(timerStarted == NO){//Only start the timer if it's not already running
                     [self startTimer]; 
                     timerStarted = YES;
                 }
             }
             else
             {
                 NSLog(@"Incorrect position.");
                 [timerObject invalidate];
                 timerStarted = NO;
                 timeTest = 0.0;
            }

         }];
    }
    else
    {
        NSLog(@"Accelerometer is not available.");
    }
}

编辑您还从块中调用 startTimer 方法,这意味着计时器不会被添加到主运行循环中.试试这个:

EDIT You're also calling your startTimer method from a block, which mean the timer isn't being added to the main runloop. Try this instead:

- (void) startTimer
{
    timeTest = 0.0;
    self.timerObject = [NSTimer timerWithTimeInterval:0.1f target:self selector:@selector(addTime) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:self.timerObject forMode:NSDefaultRunLoopMode];
}

您的 addTime 方法现在应该可以正确调用了.

Your addTime method should now get called correctly.

这篇关于在下一个动作之前,加速度计必须在给定的时间间隔内处于特定方向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆