15

私はiOSプログラミングを始めたばかりですが、これまでのところ、ここで見つけたチュートリアルと回答は、前進するための大きな助けになっています。しかし、この特定の問題は一晩中私を悩ませてきました、そして私は「正しいと感じる」答えを見つけることができません。

リモートサービスに接続するアプリケーションを作成していますが、ユーザーはそれを使用する前にサインインする必要があります。アプリケーションの使用を開始すると、最初のビューはサインインダイアログになります。以前に認証したことがある場合は、すぐに概要ページが表示されます。

このプロジェクトではストーリーボードを使用していますが(これはすばらしい機能だと思います)、ルートビューコントローラーを選択して読み込むコードのほとんどはすでに処理されています。ロジックを追加するのに最適な場所は、 :のapplication:didFinishLaunchingWithOptions:メソッドだと思いました。AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
      (NSDictionary *)launchOptions
{
    // select my root view controller here based on credentials present or not
    return YES;
}

しかし、これは2つの質問を引き起こしました:

  1. この特定のデリゲートメソッド内では、ストーリーボードに基づいてルートビューコントローラーがすでに選択(およびロード?)されています。ロードプロセスの以前の場所に移動して、最初のView Controllerの選択を上書きできますか、それとも不必要に問題を複雑にしますか?

  2. 最初のViewControllerをオーバーライドするには、ストーリーボードへの参照が必要ですが、のstoryboardWithName:bundle:コンストラクターを使用するよりも良い方法を見つけることができませんでしUIStoryboardた。それは間違っていると感じます。アプリケーションにはすでにストーリーボードへの参照が含まれているはずですが、どうすればそれにアクセスできますか?

アップデート

私はここで私の答えを見つけたので、私が持っていた2番目の問題を解決しました:

UIStoryboard:アクティブなストーリーボードを取得する正しい方法は何ですか?

NSBundle *bundle = [NSBundle mainBundle];
NSString *sbFile = [bundle objectForInfoDictionaryKey:@"UIMainStoryboardFile"];
UIStoryboard *sb = [UIStoryboard storyboardWithName:sbFile bundle:bundle];

上記は、新しいストーリーボードインスタンスを作成します。アクティブなインスタンスを取得するには、はるかに簡単です。

UIStoryboard *sb = [[self.window rootViewController] storyboard];

ストーリーボードファイル自体で、ロードするビューの識別子を設定する必要がありますLoginDialog。その後、次のようにビューをインスタンス化します。

LoginViewController *login = [sb instantiateViewControllerWithIdentifier:@"LoginDialog"];
[self.window setRootViewController:login];

別のViewController内では、次で十分です。

UIStoryboard *sb = self.storyboard;
LoginViewController *login = [sb instantiateViewControllerWithIdentifier:@"LoginDialog"];
[self presentViewController:login animated:NO completion:nil];
4

4 に答える 4

7

私はあなたと同様のシナリオを持っています。私のアプリケーションはUINavigationController、ルート ビュー コントローラーとして a を使用します。ユーザーがログインしている場合はNotLoggedInViewControllerを表示し、ログインしている場合はLoggedInViewController.

ストーリーボードでは、UINavigationController子は 1 つしか持てないため、別のルート ビュー コントローラーをプログラムで割り当てる必要があります。

カスタム ナビゲーション コントローラー クラスを作成することから始めMyNavigationControllerます。ストーリーボードで、このカスタム クラスをナビゲーション コントローラー オブジェクトに割り当てます。

引き続きストーリーボードで、両方のビュー コントローラーをモデル化し、そのうちの 1 つをナビゲーション コントローラー オブジェクトに接続します。後でコードからそれらにアクセスできるようにする必要があるため、右側の XCode インスペクターを使用して、それぞれに識別子を割り当てます。これらの識別子は任意の文字列にすることができますが、単純にするためにクラス名を使用します。

最後に、クラスにviewDidLoadメソッドを実装します。MyNavigationController

BOOL isLoggedIn = ...;

- (void)viewDidLoad {
  id rootController;
  if (isLoggedIn) {
    rootController = [self.storyboard instantiateViewControllerWithIdentifier:@"LoggedInViewController"];
  } else {
    rootController = [self.storyboard instantiateViewControllerWithIdentifier:@"NotLoggedInViewController"];
  }
  self.viewControllers = [NSArray arrayWithObjects:rootController, nil];
}
于 2012-06-02T06:58:26.100 に答える
2

私はストーリーボードをほとんど使用していませんでした。おそらく、これはあなたの質問に対する正確な答えではありません。しかし、ストーリーボードを使用せずに作成したプロジェクトで行ったことを何らかの方法で提案します。

didFinishLaunchingWithOptions AuthenticationViewControllerでは、最初に読み込まれたビューです。ログイン資格情報を要求します。入力すると、プロジェクトで使用される実際の ViewControllers (つまり、TabBar &all..) が入力されます。

UIAleretViewプロジェクトに追加された興味深い機能は、資格情報を入力すると、ユーザーに 3 つのオプションのいずれかを選択するように求めるポップアップが表示されることです。

  1. パスコードなしで資格情報を保存する
  2. 認証情報をパスコードで保存
  3. 認証情報を保存しない

ここでのパスコードは、ユーザーが入力した 4 桁の数字に他なりません。彼が「資格情報をパスコードで保存」したいときはいつでもpushViewController、デフォルトのキーボードの代わりに NumberPad を表示し、PIN の入力が完了すると表示popviewControllerします。ユーザーが「資格情報を保存しないでください」&後でアプリの再生中に他の認証オプションに移動したい場合は、TabBarController の最後のタブを「設定」タブとして追加し、その中でユーザーが認証オプションのいずれかを選択できるようにしますUIAlertView。ログイン後のアプリ起動の始まり。

認証情報をキーチェーンに保存することを忘れないでください

手短に、

  1. AuthenticationViewController-> ログイン資格情報がキーチェーンに保存されているかどうかを確認します

1.1。保存されていない場合 (つまり、3. 資格情報を保存しない) -> ログイン ページを表示します。

1.2. 資格情報がキーチェーンに保存されている場合 -> それらを抽出し、パスコードと関連付けられているかどうかを確認します。

1.2.1. パスコードに関連付けられている場合 (つまり、2.パスコードを使用して資格情報を保存する)-> パスコード ページを表示します。

1.2.2. 関連付けられていない場合(1.パスコードなしで資格情報を保存)->プロジェクトのTabBarController階層またはその他のものを表示/ロードします。ここで実際にアプリが起動します。

于 2012-05-31T04:06:40.313 に答える
-1

メインのストーリーボードが既に読み込まれているので、別のルート ビュー コントローラーをインスタンス化できるように、その参照を見つけるだけです。

UIStoryboard *mainStoryboard = self.window.rootViewController.storyboard;

self.window.rootViewController = [mainStoryboard 
    instantiateViewControllerWithIdentifier:@"view-controller-id"];
于 2014-06-16T13:29:22.530 に答える