2

データ モデルにエンティティを追加するカスタム URL スキームを実装しています。エンティティの詳細は URL に含まれています。基本的な考え方は、電子メール リンク (または別のアプリからのリンク) でアプリが開き、新しいエンティティが追加されるというものです。

問題は、応答時にアプリがどの状態になるかを確認できないことです。任意の数のビュー コントローラーが表示される可能性があります。エンティティのリストが表示されている場合は、そのエンティティの新しい行を挿入する必要があります。他のビューが画面に表示されている場合は、別の方法で対応する必要があります。一部のビューはモーダルである場合もあります。

これが発生した場合、単純なパターンで満足できます。ユーザーが現在行っていることは何でも中止し、ルート ビュー コントローラーにポップします。ここから、追加された新しいエンティティを表示するコントローラにプッシュします。

表示されているモーダルを常に閉じてルートにポップすることを実験しました。これは、表示されているものを正確に知る必要がないという利点があります。

[(UINavigationController *)self.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
[(UINavigationController *)self.window.rootViewController popToRootViewControllerAnimated:NO];

これはかなりうまく機能しますが、不十分な場合が少なくとも 2 つあります。

  1. モーダルが提示されたときに何らかのオブジェクトが作成された場合 (モーダルは新しいオブジェクトを変更するために使用されます)、ユーザーがキャンセルした場合にオブジェクトを削除するのはデリゲートの責任であり、エンティティは存続します。
  2. が表示されている場合UIActionSheet、すべての賭けはオフです。これを表示したコントローラーを知り、そのコントローラーにアクセスし、アクション シートを閉じるようにメッセージを送信しない限り、これを閉じることはできません。そうしないと、ルート ビュー コントローラーがポップされますが、アクション シートは画面に表示されたままになります。それを表示したコントローラーがなくなっているため、アクションシートを続けてタップすると、もちろんクラッシュが発生します。

どうすればこれを確実に処理できますか? 現在表示されているView Controllerを特定して、各シナリオを順番に処理する必要がありますか? または、コントローラーを追加したり、アプリケーションのフローを変更したりするたびに更新する必要のない、よりスケーラブルなソリューションはありますか?

4

1 に答える 1

3

いくつかのことをしようとしているようです:

  1. ユーザーがカスタム URL をクリックしたときに、モデルに「エンティティ」を追加する必要があります。
  2. EntityListViewControllerこの新しいエンティティを、ViewController スタック上にある場合とない場合がある、ある種の に表示したいとします。
  3. 上のすべてのView Controllerをポップオフしたい(かもしれません)EntityListViewController
  4. 新しいエンティティが追加されたことをユーザーに知らせたい (おそらく項目 2 を実行するだけで)。
  5. ある種の をプッシュしたいEntityViewController、または現在EntityViewControllerView Controller スタックに がある場合は、新しいエンティティのデータをリロードしたい。

URLクリックの処理と新しいモデルオブジェクトの挿入について明示的に質問しなかったため、アイテム1の準備ができているようです。

残りについては、柔軟で MVC っぽいパターンは NSNotificationCenter を使用することです。

新しいモデル オブジェクトを挿入するコードは、通知を「投稿」します。

[[NSNotifcationCenter defaultCenter] postNotificationName:@"entity_added" object:myNewEntity];

次に、さまざまな UI 要素 (UIAlertView および UIViewController サブクラスなど) がこの通知をリッスンし、いくつかの便利なアクションを実行します (自分自身を閉じる、 または の場合はEntityListViewController自分EntityViewController自身をリロードするなど)。

たとえば、UIViewControllerサブクラスはこれを行う場合があります。

-(void) viewDidLoad
{
  [super viewDidLoad];
  [[NSNoticationCenter defaultCenter] addObserver:self selector:@selector(onNewEntity:) name:@"entity_added" object:nil];


-(void) onNewEntity:(MyEntity*)entity
{
   // close, or redraw or...
}

-(void) dealloc
{
  [[NSNoticationCenter defaultCenter] removeObserver:self];
  // if not using ARC, also call [super dealloc];
}

あなたの人生をシンプルに保つために (そして、さまざまな UI の状態についてあまり心配しないでください)、通知が発生したときにこれを行うことを検討します。

  1. 再描画自体を行いEntityListViewControllerます (その上に何かがあるかどうかは関係ありません)。
  2. ナビゲーション バー (または常に表示されていることがわかっている別の場所) にある種の短命のインジケーターを表示するか、サウンドを再生して、エンティティが追加されたことをユーザーに知らせます。
  3. それだけです。

このアプローチを採用した場合、ユーザーが行っている/していたことへの影響は最小限に抑えられますが、ユーザーが に戻ると、EntityListViewControllerすべての新しいエンティティが既に表示されています。

明らかに、カスタム URL のクリックによって既存のエンティティが削除される可能性がある場合は、そのエンティティに関連するビュー コントローラーを削除することがより重要になります。しかし、これは同じパターンを使用して行うこともできます。モデルまたはコントローラーに通知を投稿させ、さまざまな UI 要素に通知をリッスンさせて適切なアクションを実行させます。

于 2013-01-02T02:03:33.383 に答える