ナビゲーション コントローラー スタック、サブビュー、またはモーダル コントローラーを使用せずにビュー コントローラーの変更をアニメーション化しますか? 質問する

ナビゲーション コントローラー スタック、サブビュー、またはモーダル コントローラーを使用せずにビュー コントローラーの変更をアニメーション化しますか? 質問する

NavigationController には、管理する ViewController スタックと制限されたアニメーション遷移があります。

既存のビュー コントローラにサブビューとしてビュー コントローラを追加するには、サブビュー コントローラにイベントを渡す必要がありますが、これは管理が面倒で、ちょっとした煩わしさが伴い、実装するときに一般的に悪いハックのように感じられます (Apple もこれを行わないように推奨しています)。

モーダル ビュー コントローラーを再度表示すると、ビュー コントローラーが別のビュー コントローラーの上に配置され、前述のイベント受け渡しの問題は発生しませんが、ビュー コントローラーが実際に「交換」されるのではなく、積み重ねられます。

ストーリーボードは iOS 5 に限定されており、ほぼ理想的ですが、すべてのプロジェクトで使用できるわけではありません。

上記の制限なしにビュー コントローラーを変更し、それらの間のアニメーション遷移を可能にする方法についての明確なコード例を提示できる人はいますか?

近い例ですが、アニメーションはありません:ナビゲーション コントローラーなしで複数の iOS カスタム ビュー コントローラーを使用する方法

編集: ナビゲーション コントローラーの使用は問題ありませんが、アニメーション化された遷移スタイル (単なるスライド効果ではない) が必要であり、表示されるビュー コントローラーは完全に入れ替えられる必要があります (スタックされていない)。2 番目のビュー コントローラーがスタックから別のビュー コントローラーを削除する必要がある場合、カプセル化が不十分です。

編集 2: この質問のベース OS は iOS 4 であるはずです。ストーリーボード (上記) について言及したときにそのことを明確にすべきでした。

ベストアンサー1

編集: どの方向でも機能する新しい回答。元の回答は、インターフェイスが縦向きの場合にのみ機能します。 これは、ビューを別のビューに置き換えるビュー遷移アニメーションは、ウィンドウに追加された最初のビューの少なくとも 1 レベル下のビューで発生する必要があるためです (例window.rootViewController.view.anotherView)。

私は というシンプルなコンテナクラスを実装しましたTransitionController。これは次の場所にあります。出典: github.com

余談ですが、再利用しやすいので、別のクラスで実装することを好みます。それが嫌なら、同じロジックをアプリのデリゲートに直接実装するだけで、クラスは不要になりますTransitionController。ただし、必要なロジックは同じです。

次のように使用します。

アプリデリゲートで

// add a property for the TransitionController

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    MyViewController *vc = [[MyViewContoller alloc] init...];
    self.transitionController = [[TransitionController alloc] initWithViewController:vc];
    self.window.rootViewController = self.transitionController;
    [self.window makeKeyAndVisible];
    return YES;
}

任意のビューコントローラから新しいビューコントローラに移行するには

- (IBAction)flipToView
{
    anotherViewController *vc = [[AnotherViewController alloc] init...];
    MyAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
    [appDelegate.transitionController transitionToViewController:vc withOptions:UIViewAnimationOptionTransitionFlipFromRight];
}

編集: 元の回答は以下です - 縦向きの場合にのみ機能します

この例では、次の仮定を立てました。

  1. rootViewControllerウィンドウのとしてビューコントローラが割り当てられています

  2. 新しいビューに切り替えるときは、現在の viewController を新しいビューを所有する viewController に置き換えます。常に、現在の viewController のみが有効です (割り当てられているなど)。

コードは簡単に変更して異なる動作をさせることができますが、重要な点はアニメーション化された遷移と単一のビュー コントローラです。ビュー コントローラを に割り当てる以外の場所に保持しないようにしてくださいwindow.rootViewController

アプリデリゲートの遷移をアニメーション化するコード

- (void)transitionToViewController:(UIViewController *)viewController
                    withTransition:(UIViewAnimationOptions)transition
{
    [UIView transitionFromView:self.window.rootViewController.view
                        toView:viewController.view
                      duration:0.65f
                       options:transition
                    completion:^(BOOL finished){
                        self.window.rootViewController = viewController;
                    }];
}

ビューコントローラでの使用例

- (IBAction)flipToNextView
{
    AnotherViewController *anotherVC = [[AnotherVC alloc] init...];
    MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate;
    [appDelegate transitionToViewController:anotherVC
                             withTransition:UIViewAnimationOptionTransitionFlipFromRight];
}

おすすめ記事