54

デバイスの向きがゲームの状態に影響するゲームがあります。ユーザーは、横向き、縦向き、逆横向きをすばやく切り替える必要があります。これまでのところ、次の方法でオリエンテーション通知用にゲームを登録しています。

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

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

4

6 に答える 6

144

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];
}

これは、向きごとにビューを変更できる最速の方法だと思います

于 2012-08-23T07:09:31.070 に答える
25

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

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

加速度計は 3 つの軸すべてで加速度 (重力を含む) を測定するので、実際の向きを把握するのに問題はありません。

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

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

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

加速度計の使用

于 2012-08-23T07:06:47.247 に答える
21

使わなかった理由

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

?

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

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

またはこれ

-(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation

フクロウが役に立てば幸いです)

于 2012-08-23T06:53:20.707 に答える
12

私の場合、処理UIDeviceOrientationDidChangeNotificationはより頻繁に呼び出され、(FaceDown、FaceUp) のためにUIDeviceOrientation常に等しいとは限らないため、適切な解決策ではありませんでした。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");
    }
}
于 2014-12-23T08:26:52.450 に答える
5

@vimalの回答は私に解決策を提供しませんでした。オリエンテーションは現在のオリエンテーションではなく、以前のオリエンテーションからのようです。それを修正するために、私は使用します[[UIDevice currentDevice] orientation]

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

それで

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

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

于 2014-02-10T09:57:06.553 に答える
5

次の場所で変更を加えてみてください。

- (void) viewWillLayoutSubviews {}

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

于 2013-03-25T19:36:56.033 に答える