1. ホーム
  2. iphone

[解決済み] ナビゲーションコントローラスタック、サブビュー、モーダルコントローラを使用せずに、ビューコントローラの変化をアニメーション化する?

2022-05-17 13:39:36

質問

NavigationControllerはViewControllerのスタックを管理し、アニメーションの遷移を制限しています。

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

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

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

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

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

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

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

どのように解決するのですか?

編集:どの方向でも動作する新しい答え。 オリジナルの答えは、インターフェイスが縦向きのときのみ動作します。これは、ビューを別のビューに置き換えるビュー遷移アニメーションが、ウィンドウに追加された最初のビューより少なくとも1レベル下のビューで発生しなければならないためです (例. window.rootViewController.view.anotherView ).

という簡単なコンテナ・クラスを実装しました。 TransitionController . これは、以下の場所で見つけることができます。 https://gist.github.com/1394947 .

余談ですが、私は別のクラスで実装する方が再利用しやすいと思います。もしそうしたくない場合は、同じロジックをアプリのデリゲートに直接実装することで 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だけが生きています(例:alloc'ed)。

重要なのは、アニメーションによる遷移と単一のビューコントローラです。ビューコントローラを 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];
}