web-dev-qa-db-ja.com

iOSの向きの変化を即座に検出

デバイスの向きがゲームの状態に影響するゲームがあります。ユーザーは、横向き、縦向き、および横向きの向きをすばやく切り替える必要があります。これまでに、方向通知用のゲームを次の方法で登録しています。

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

しかし、あまりにも遅すぎます-電話を回転させてから実際に通知が発せられるまでに約2秒の遅れがあるようです。デバイスの向きの変化を即座に検出する方法が必要です。私はジャイロスコープを試してみましたが、それが私が探している解決策であるかどうかを知るにはまだ十分に精通していません。

53
GoldenJoe

あなたが話しているdelayは、実際には誤った(不要な)方向変更通知を防ぐためのフィルターです。

instantデバイスの向きの変化の認識については、自分で加速度計を監視する必要があります。

加速度計は、3つの軸すべてで加速度(重力を含む)を測定するため、実際の方向を把握するのに問題はないはずです。

加速度計の使用を開始するためのコードは次の場所にあります。

iPhoneアプリの作り方–パート5:加速度計

そして、この素敵なブログは数学の部分をカバーしています:

加速度計を使用

23
Rok Jarc

viewWillAppear関数に通知機能を追加します

-(void)viewWillAppear:(BOOL)animated{
  [super viewWillAppear:animated];
  [[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(orientationChanged:)    name:UIDeviceOrientationDidChangeNotification  object:nil];
}

方向の変更はこの機能を通知します

- (void)orientationChanged:(NSNotification *)notification{
   [self adjustViewsForOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
}

順番に、moviePlayerControllerフレームの向きが処理されるこの関数を呼び出します

- (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation {

    switch (orientation)
    {
        case UIInterfaceOrientationPortrait:
        case UIInterfaceOrientationPortraitUpsideDown:
        { 
        //load the portrait view    
        }

            break;
        case UIInterfaceOrientationLandscapeLeft:
        case UIInterfaceOrientationLandscapeRight:
        {
        //load the landscape view 
        }
            break;
        case UIInterfaceOrientationUnknown:break;
    }
}

viewDidDisappearで通知を削除します

-(void)viewDidDisappear:(BOOL)animated{
   [super viewDidDisappear:animated];
   [[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}

これは最速のuは向きごとにビューを変更した可能性があります

143

使用しなかった理由

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

または、これを使用できます

-(void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration

またはこれ

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

フクロウが役に立つことを願って)

21
Arthur

私の場合、UIDeviceOrientationDidChangeNotificationは頻繁に呼び出され、UIDeviceOrientationは(FaceDown、FaceUp)のためにUIInterfaceOrientationと必ずしも等しくないため、適切な解決策ではありませんでした。

UIApplicationDidChangeStatusBarOrientationNotificationを使用して処理します。

//To add the notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeOrientation:)

//to remove the
[[NSNotificationCenter defaultCenter]removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];

 ...

- (void)didChangeOrientation:(NSNotification *)notification
{
    UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;

    if (UIInterfaceOrientationIsLandscape(orientation)) {
        NSLog(@"Landscape");
    }
    else {
        NSLog(@"Portrait");
    }
}
11
B.S.

変更を行ってみてください:

- (void) viewWillLayoutSubviews {}

サブビューが再びレイアウトされると、コードは方向が変わるたびに実行されます。

5
powerj1984

@vimalの回答では解決策が得られませんでした。向きは現在の向きではなく、以前の向きからのもののようです。修正するには、[[UIDevice currentDevice] orientation]を使用します

- (void)orientationChanged:(NSNotification *)notification{
    [self adjustViewsForOrientation:[[UIDevice currentDevice] orientation]];
}

それから

- (void) adjustViewsForOrientation:(UIDeviceOrientation) orientation { ... }

このコードを使用して、現在の向きの位置を取得します。