0

アプリケーションでメソッドを実行しようとしていますが、特定の時間間隔で電話が正しい加速度計の向きになった後でのみです。私が抱えている問題は、加速度計が更新されるたびにタイマーがリセットされることです。加速度計が更新されるたびにではなく、1回だけ開始する時間をトリガーする方法を理解できませんでした。

// 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 内

#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

どんな援助も素晴らしいでしょう!

4

1 に答える 1

0

1 つの方法は、BOOL フラグを挿入してタイマーが開始したことを示し、タイマーが不必要に再開始されるのを防ぐことです。次に、タイマーが無効になったときにフラグをリセットします。したがって、次のようなものがあります(テストされていませんが、要点はわかると思います):

- (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.");
    }
}

EDITまた、ブロックからメソッドを 呼び出しています。startTimerつまり、タイマーがメインの実行ループに追加されていません。代わりにこれを試してください:

- (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が正しく呼び出されるはずです。

于 2013-08-01T16:47:25.727 に答える