3

私は iOS 開発にまったく慣れていないため、このような簡単なタスクを達成する方法をまだ管理していません。

生のxCode 4.4.1「Single View Application」プロジェクトがあります。

たとえば、4 つの画面が必要で、それぞれに他のビューに切り替えるためのボタンがあります。

画面は階層化されていません。たとえば、画面 1 から画面 2 または画面 3 に切り替えたり、画面 2 から画面 4 に切り替えたりできるようにしたい。アプリケーションの実行時 - 最初の画面が表示されますが、そのステータスは「ルート」または「メイン」ではなく、他の画面とは異なり、単なる一般的な画面です。

私の条件は次のとおりです。

  1. デフォルトのメイン ストーリーボード ファイルしかありません (xib ソリューションは適切ではありません)。
  2. ナビゲーション コントローラーや類似の事前構造化されたものを使用することに依存したくありません。

WWDC 2011 のセッション 102 で説明されているように、子コントローラーを使用してコンテナー コントローラーを何らかの方法でセットアップする必要があるように思えますが、コードを適切に記述する方法がわからないため、メインのストーリーボードと競合しません (ここSOの他の同様のトピックからxibベースのソリューションを使用しようとして2回失敗しました)。

私の経験ではまだ部分的なヒントに頼ることができないため、完全に機能する例を非常に高く評価しますが、それらも問題ありません。

これをプログラムで行うソリューション (ドラッグなどの xCode UI 機能を使用しない) が推奨されます。

ありがとう!

更新: 切り替えるときに、毎回新しい画面をインスタンス化するのではなく、既存の画面が既に存在する場合は再利用します。

更新 2: この問題のために簡略化された私の使用例:

すべての一般的なログイン/ログアウト/その他の状況を処理するための対応するモーダル画面を備えた登録画面があります。ログイン/登録手順が完了すると、アプリの「メイン」アプリ画面になります。メイン画面はユーザー固有の情報に大きく依存するため、登録画面/コントローラーをメイン画面のモーダルにしたくないので、これらの画面を階層化しないようにしたいと思います。この単純化された状況に対して、次のフローを用意することを考えています。

1) ユーザーはまだログインしていません - 登録画面が表示されます。後で、登録後。手順が完了しました- 「メイン」画面に切り替えます(これは私が気付いていない重要なポイントです。それがこの問題の理由です)。

2) ユーザーがログインし、アプリによって認識される - 「メイン」画面が表示されます。

私が説明したような登録と「メイン」画面を持つことは、「タブ付きアプリケーション」テンプレートに「タブコントローラー」機能をそのまま持つ状況を除外します (または何をしますか?)。私の場合、タブバーを完全に無効にしたいからです。ナビではありません。& ナビゲーション バー機能ですが、reg 間の遷移を実行する方法にすぎません。および「メイン」画面-これが私の質問で「手で」という意味です。

最終更新:

タブ バー コントローラーを試した後、このユース ケースでは、ナビゲーション バーを無効にした状態でナビゲーション コントローラーを使用し (タブ バー コントローラーに類似したものは見つかりませんでした)、画面の切り替えをperformSegueWithIdentifierメソッドと切り替えによって管理することになりました。 「手で」viewControllersナビゲーションスタックを操作することによってそれらを。

回答ありがとうございました!

4

2 に答える 2

2

あなたの質問に対する簡単な答えは、タブ バー コントローラーを使用することです。これは、実際には多くの複雑さを管理する単純なコントロールであり、再実装することは、初心者や、タブ バー コントローラーの動作に慣れているアプリケーションのユーザーにとっては良い考えではありません。

タブ バー コントローラーにはプロパティ ( viewControllers) があり、コントロールを押しながら他のシーンにドラッグすることで、ストーリーボードに入力できます。タブ バー コントローラーは、これらのビュー コントローラーのそれぞれに問い合わせて、タブ バー (名前と画像、適切な数のアイテム、バーに収まらない場合は "More" コントローラー) を構築し、それぞれの切り替えを処理します。含まれているビューとタブ バーのサイズを変更して、回転イベントを処理します。したがって、タブ バー コントローラーのビューには 2 つのサブビューが含まれます。1 つはタブ バーを保持し、もう 1 つは現在表示されているビュー コントローラーのビューを保持します。

その機能をすべて自分で複製する必要がありますが、これは初心者にとってはかなり複雑であり、確かにスタック オーバーフローの回答の範囲外です。既存の機能を複製するという事実は、本当にそのように作業する必要があるかどうかについての危険信号でもあります。

重要な部分 (「リレーションシップ - ビュー コントローラー」) はカスタム コンテナー ビュー コントローラーでは使用できないため、タブ バー タイプのコントローラーを自分で実装することは、ストーリーボードでもサポートされていません。したがって、コードでUIを設定し、View Controllerを手動でインスタンス化して関係を設定する必要がありますが、これはメインのストーリーボードと衝突する可能性があります.質問のタイトルなので、少し混乱しています。

それでもやりたい場合にこれ実装する方法の簡単な概要:

  • カスタム UIViewController を作成する
  • viewControllers プロパティと、切り替えを処理するある種のコントロール (おそらくセグメント化されたコントロール) を追加します。
  • プロパティが設定されている場合、viewControllersセグメント化されたコントロール セグメントの 1 つのタイトルとして設定するタイトルを取得します。配列の最初の項目のビューをメイン ビューのサブビューとして追加し (適切なフレームを使用して、セグメント化されたコントロールをカバーしないようにします)、および を使用して子ビュー コントローラーとして追加します[self addChildViewController:vc]) [vc didMoveToParentViewController:self]
  • セグメント化されたコントロールの値が変更されたら、現在のビュー コントローラーのビューをビュー階層 ( removeFromSuperview) とビュー コントローラー階層 ( removeFromParentViewController) から削除し、上記のコードを使用して新しく選択したビュー コントローラーのビューを追加します。
于 2012-08-12T08:23:06.077 に答える
2

おそらく最も簡単な方法は、ストーリーボードでセグエを使用することです。

メインのView Controllerから他のそれぞれに右クリックしてドラッグします。作成するセグエのタイプを尋ねられ、モーダルを選択します。

次に、識別子プロパティで各セグエに一意の識別子文字列を指定してください。

さて、コードから、これらのView Controllerの1つをアクティブにしたいときはいつでも呼び出します

[self performSegueWithIdentifier:@"Foo Segue" sender:(id)sender];

上記の送信者オブジェクトは、必要なものであれば何でもかまいません。通常は、表示する準備ができている View Controller に渡したい情報です。

ここで、セグエが表示される直前に、プログラムによって、またはストーリーボードで定義されたインタラクションから直接、prepareForSegueメソッドが呼び出されます。したがって、「メイン」View Controllerのコードで、このようなことを行います。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // You have access to the view controller that is getting ready to be
    // displayed, as well as the identifier, so you can set values or whatever
    // before the view controller is presented.
    if ([segue.identifier isEqualToString:@"Foo Segue"]) {
        FooViewController *vc = segue.destinationViewController;
        // The view controller is completely instantiated, and you can do any
        // setup work, like setting property values on the view controller
        // to give it its model, or whatever else you want to do.
    }
}

ここで、そのコントローラーがいつ完了したかを知る方法が必要です。これにはいくつかの方法があります。提示されたView Controllerは、それ自体を閉じることができます。または、デリゲートまたは通知を使用して、提示しているView Controllerに、完了したため破棄する必要があることを伝えることができます。

あなたの場合、提示された VC 自体を却下しても問題ないかもしれません。だから、電話するだけ

[self dismissViewControllerAnimated:YES completion:nil];

セグエを使用したくない場合は、VC をストーリーボードから直接ロードする (または独自の nib を与える) 必要があります。ストーリーボードからインスタンス化するには、インスタンス化するビュー コントローラーに独自の識別子タグを与える必要があります (再度プロパティ ペインを見て、VC でプロパティを設定します)。

次に、これを行うことができます(このコードを格納するVCが、インスタンス化しようとしているVCと同じストーリーボードにあると仮定します)...

FooViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"FooViewController"];

次に、実際にそのコントローラーを提示します...

[self presentViewController:vc animated:YES completion:nil];

もちろん、これを行うには他にもいくつかの方法があり、各アプローチにはいくつかの長所と短所があります。試してみて、関連するドキュメントを読んで、どの方法を使用するかについて知識に基づいた決定を下すことをお勧めします。

いずれにせよ、上記はあなたの目標への幾分簡単な道を与えるはずです.

于 2012-08-11T13:52:55.927 に答える