4

私はこのオブザーバーを使用しています:UIDeviceOrientationDidChangeNotificationユーザーがデバイスの向きを変更しているときを検出します。向きが横向きに変わったとき、私は新しいものを提示するか、彼が縦向きに戻したときにUIViewControllerこれを却下します。UIViewController

私の問題は、ユーザーがデバイスを何回も速く回転させ始めたときに始まり、次のエラーが発生するまでアプリケーションが狂ってしまいます。

警告: ウィンドウ階層にないビューで表示しようとしています!`.

アニメーションが終了するまで待ってから回転を変更する最善の方法は何ですか?

これは、Presenting View Controllerで使用しているものです。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self beginDeviceOrientationListener];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)beginDeviceOrientationListener
{
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
}

- (void)orientationChanged:(NSNotification *)notification
{
    UIDevice *device = notification.object;
    switch (device.orientation)
    {
        case UIDeviceOrientationLandscapeLeft:
        case UIDeviceOrientationLandscapeRight:
        {
            TheViewControllerToPresent *viewController = [[TheViewControllerToPresent alloc] init];
            [self presentViewController:viewController animated:YES completion:nil];
            [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeRight] forKey:@"orientation"];
            [[UIApplication sharedApplication] setStatusBarOrientation:[[[UIDevice currentDevice] valueForKey:@"orientation"] integerValue] animated:YES];
            [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
        }
            break;

        default:
            break;
    }
}

これは、Presented ビュー コントローラーで使用しているものです。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self beginDeviceOrientationListener];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)beginDeviceOrientationListener
{
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationChanged:) name:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
}

- (void)orientationChanged:(NSNotification *)notification
{
    UIDevice *device = notification.object;
    switch (device.orientation)
    {
        case UIDeviceOrientationPortrait:
        {
            [self dismissViewControllerAnimated:YES completion:nil];
            [[UIDevice currentDevice] setValue:[NSNumber numberWithInteger:UIInterfaceOrientationPortrait] forKey:@"orientation"];
            [[UIApplication sharedApplication] setStatusBarOrientation:[[[UIDevice currentDevice] valueForKey:@"orientation"] integerValue] animated:YES];
        }
            break;
        default:
            break;
    }
}
4

1 に答える 1

3

私が自分で使用している最も簡単な解決策は、アニメーションの進行中にユーザーが変更を加えないようにすることです。

これを行うには、アニメーションの開始時に次のコードを追加します。

[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];

そして完了ハンドラに:

[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[UIApplication sharedApplication] endIgnoringInteractionEvents];

ユーザーはデバイスを回転できますが、アニメーション中にイベントが生成されないため、アニメーションが衝突しません。ただし、アニメーションが終了したら、向きを明示的に確認する必要があります。

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

別のアニメーションを開始する必要があるかどうかを確認します。

于 2015-05-07T13:43:03.200 に答える