1

UINavigationControllerのデフォルトのポップ アニメーションが予期しない動作をするという問題が発生しています。

この問題は、コントローラーのUITraitCollection.

私はユニバーサルアプリを持っていUIPresentationControllerます.iPadでは、ナビゲーションを部分モーダルで表示するカスタムがあり、その幅は画面幅の一部です。したがって、のプロパティでをオーバーライドしhorizontalSizeClassてコンパクトにするので、この「ハーフ モーダル」に表示されるすべてのコントローラーは iPhone レイアウトを想定します。UIPresentationControlleroverrideTraitCollection

そのサイズ クラスをオーバーライドすると、バグが発生するようです。突然、その「ハーフモーダル」内でコントローラーをポップすると、アニメーションが横向きでめちゃくちゃになります (左または右にジャンプします)。

これがどのように見えるかの例です: 予期せぬポップアニメーション

試み

まず、オーバーライドを取り除くとtraitCollection、バグはなくなります。ただし、これらのビューは通常の環境でも他の場所で再利用されるため、水平サイズ クラスをオーバーライドしたいのは明らかです。

horizontalSizeClassしたがって、次のように、モーダルの子の を他の方法でオーバーライドしようとしました。

  • モーダル Nav を使用してUINavigationControllerDelegate各子のtraitCollectionオン をオーバーライドするnavigationController:didShowViewController:animated:– これは違いがないように見えました
  • traitCollection プッシュする前に、最初の nav 子で 2 番目の子をオーバーライドする

そのようです:

[self.navigationController setOverrideTraitCollection:compactTraitCollection forChildViewController:secondaryController];
[self.navigationController pushViewController:secondaryController animated:YES];

興味深いことに、これによりポップ アニメーションのバグが修正されますが、プライマリ コントローラー ( self) はまだレギュラーのままhorizontalSizeClassです ... さらに、これは悪い習慣のようです。私のView Controllerは、プレゼンテーションについて何も知る必要はありません! これは によって処理される必要があり、プレゼンテーション コントローラーにプロパティUIPresentationControllerがあるという事実によってサポートされているようです。overrideTraitCollection

4

1 に答える 1

2

原因は、supportedInterfaceOrientationsサイズ クラスに依存する の実装であることが判明しました。

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    // Don't do this if you ever override size classes
    if (self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassRegular)
    {
        return UIInterfaceOrientationMaskAll;
    }
    return UIInterfaceOrientationMaskPortrait;
}

horizontalSizeClass「ハーフモーダル」コントローラーの は使用するようにオーバーライドされたため、UIUserInterfaceSizeClassCompactポートレートのみの向きを想定していました。ナビゲーション コントローラーは、それを処理する方法を知りませんでした。

ソリューション:

デバイスの種類に依存するように上記のコードを変更すると、問題が修正されます。

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
    // Basing off of size classes causes unexpected behavior when overriding size classes - use interface idiom instead
    if (self.traitCollection.userInterfaceIdiom == UIUserInterfaceIdiomPhone)
    {
        return UIInterfaceOrientationMaskAll;
    }
    return UIInterfaceOrientationMaskPortrait;
}

これはおそらく最初に進むべき道だったはずですが、デバイスに依存せず、サイズ クラスのみに依存することを Apple が奨励していることを考えると、私はそうしませんでした。

とにかく、繁栄のために、これをデバッグするために使用したテストプロジェクトを次に示します: https://github.com/bradgmueller/half-modal-test

于 2016-04-05T15:21:48.770 に答える