0

私のアプリには次のビューコントローラーが組み込まれています。提示するコントローラーは「PatientSelectViewController」(コントローラーAと呼びます)であり、テキストフィールドに患者IDを手動で入力するか、「バーコードのスキャン」ボタンを押して別のビューコントローラー(「BarcodeScanViewController」)へのセグエを実行できます。 "(それをコントローラーBと呼びましょう)。

Bがバーコードのスキャンを終了して結果(患者ID)を返すと、私は提示しているView Controller(A)にそのことを通知し、AはデータベースでIDを検索する責任があります。この時点で、コントローラーBを閉じる必要があります。IDが見つかった場合は、3番目のビューコントローラーである「PatientConfirmViewController」に移行します(これをCと呼びます)。ただし、IDが見つからない場合は、そのことを示すポップアップメッセージが必要であり、コントローラーBに再度移動して、バーコードを再度スキャンします。

同様に、ユーザーがIDをスキャンする代わりに手動でテキストフィールドに入力することを決定した場合、成功したIDはコントローラーCに移動し、失敗したIDはポップアップメッセージを表示して、コントローラーAに残ります。

また、コントローラーをナビゲーションコントローラーに埋め込んで、以前のViewControllerに戻るためのタブバーボタンを常に用意したいと思います。たとえば、BまたはCからAに戻るためのタブバーボタンがあります。理想的には、バーコードスキャンが成功した後にCに到達した場合、タブバーボタンでAではなくBに戻るようにします。-ユーザーがこのIDを確認したくないと判断した場合、ユーザーはバーコードを再スキャンする可能性が高いという考えです。しかし、これは重要ではありません。

何らかの理由でこれを実装するのに問題があります。失敗した動作の例を次に示します。Aを呼び出してからBを呼び出し(バーコードをスキャンするため)、データベースにあることがわかっているバーコードをスキャンします。これにより、患者情報が表示された状態でCに正しく移動します。しかし、タブバーボタン「EnterPatient ID」を使用してAに戻ることにしました。次に「Scanbarcode」ボタンをもう一度押して、以前と同じバーコードをもう一度スキャンしますが、今回はCへの移行が成功する代わりに、この画面-ねじ込まれたタブバーに注意してください!「IDの確認」と「患者IDの入力」を同時に言う必要があり、ボタンはログイン(最初にAを呼び出したコントローラー)と「バーコードのスキャン」(つまり、コントローラーB)に戻ります。以前にポップアップされたことがないかのように! タブバーをめちゃくちゃ これは、2回または3回以上のスキャンが成功した後にランダムに発生する可能性があります。ログには次の情報が表示されます。

ネストされたプッシュアニメーションにより、ナビゲーションバーが破損する可能性があります

の外観遷移を開始/終了するための不均衡な呼び出し。

予期しない状態でナビゲーション遷移を終了します。ナビゲーションバーのサブビューツリーが破損する可能性があります。

これが私がそれを実装した方法です:

ビューコントローラAの場合:

-(void)prepareForSegue: (UIStoryboardSegue *)segue sender: (id)sender
{
    if ([[segue identifier] isEqualToString:@"BarcodeScanView"])
    {
        self.p_usingBarcodeScan=YES;
        [[segue destinationViewController]setViewDelegate:self]; //sets itself as a delegate for receiving the result of a barcode scan from controller B 
    }
    if ([[segue identifier] isEqualToString:@"ConfirmID"])
    {
        [[segue destinationViewController] setP_userInfo:p_userInfo]  ; //passes the data to the controller C
    }
}

バーコードスキャン結果を受信するためのデリゲートメソッド(まだコントローラーAにあります):

- (void) didScanBarcode:(NSString *)result
{

    self.p_userID = result;

    [self.navigationController popViewControllerAnimated:YES];//Pop B from the navigation stack to return to A - is this right????

    //Run the database query
    [self lookUpID];
}

データベースでIDを検索するメソッド(まだAにあります):

- (void) lookUpID{


    /*.....
    Does something here and gets a result of the lookup...
    */

    // Do something with the result
    if ([[result  p_userName] length] > 0 ){ //Found the user!
        p_userInfo = result;
        [self performSegueWithIdentifier: @"ConfirmID" sender: self];

    }
    else {
        UIAlertView * messageDlg = [[UIAlertView alloc] initWithTitle:nil message:@"User was not found. Please try again"
                                                             delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
        [messageDlg show];

        //Here I'd like to perform this seque to B only if I got here after a barcode scan... 
        //Otherwise I am just staying in A...
        if (self.p_usingBarcodeScan == YES ){
            [self performSegueWithIdentifier: @"BarcodeScanView" sender: self];
        }  
    }
    return;
}

完全を期すために、Bでバーコードをスキャンできたら、これを次のように呼んでいます。

- (void)decodeResultNotification: (NSNotification *)notification {

    if ([notification.object isKindOfClass:[DecoderResult class]])
    {
        DecoderResult *obj = (DecoderResult*)notification.object;
        if (obj.succeeded)
        {
            decodeResult = [[NSString alloc] initWithString:obj.result];

            [[self viewDelegate] didScanBarcode:decodeResult];
        }
    }
}

AからB、AからCのプッシュシーケンスを使用しており、ストーリーボードを使用しています。これがストーリーボードのスナップショットで、AからB( "BarcodeScan")とAからC( "ConfirmID")のセグエが表示されています。どちらもプッシュセグエです:

ストーリーボードスナップショット

よろしくお願いします!

4

2 に答える 2

0

OK、私は自分の質問に部分的に答えようとしています。上記のHeWasの提案を実装した後でも、私の問題は解決せず、さらに増えました(これらの詳細については、ディスカッションスレッドhttps://chat.stackoverflow.com/rooms/23918/discussion-between-peterd-and-heのコメントにあります。 -だった)

しかし、いくつかの変更により、「ネストされたプッシュアニメーションはナビゲーションバーの破損につながる可能性があります」というログメッセージをグーグルで検索し、この回答を読んでしまいました:https : //stackoverflow.com/a/5616935/1959008問題は使用していました

   [self.navigationController popViewControllerAnimated:YES]; 

つまり、アニメーションがYESに設定されています。NOに設定すると、タブバーの問題は解消されました(いくつかの小さな癖が残っているので、すぐに解決したいと思っています)。これは本当に奇妙です-私には機能というよりはバグのように見えますが、もちろん間違っている可能性があります...

于 2013-02-05T19:21:24.067 に答える
0

現在、ナビゲーション コントローラーを使用してセグエをプッシュしているか、モーダル セグエで表示しているかはわかりません。

ここ:

    [self.navigationController popViewControllerAnimated:YES];//Pop B from the navigation stack to return to A - is this right????
    [self dismissViewControllerAnimated:YES completion:nil];**//is this right???**

1 つ目はプッシュ セグエから戻る場合に適切で、2 つ目はモーダル/提示セグエに適しています。プッシュ リターン メソッドは、ナビゲーション コントローラーで [戻る] ボタンを使用したときに実際に起こることです。

更新 ナビゲーション方法を少し解く必要があると思います。私が提案すること

  • B には、次のデリゲート メソッドがあります。

    • 患者IDを確認します
    • 良ければ、 A に self.p_userID を設定します
    • BOOL の成功/失敗を B に返します
      。_
  • その結果に基づいて、次のいずれか:

    • 飛び降りる(Bで直接使用できます[self.navigationController popViewController])または

    • B でアラートを表示します。B に戻るボタンと (おそらく) 再スキャン ボタンがある場合、アラートで選択肢を提示する必要はないかもしれません。

A : _

- (void) viewWillAppear:(BOOL)animated
{
    NSLog (@"viewControllers %@",self.navigationController.viewControllers);

    [super viewWillAppear:animated];
    if (self.p_userID) {
        [self performSegueWithIdentifier: @"ConfirmID" sender: self];
        self.p_userID = nil;
    }
}

(この performSegue は、まだ B にいる間に self.p_userID を設定した場合にのみ発生するはずです)

入力されたユーザー ID ロジックはより単純です。もう一度、患者 ID を確認します。そこにない場合は、A でアラートをスローします (ここでも、すべてのナビゲーション オプションがアラートなしで使用できるため、選択肢を提示する必要はありません)。そこにある場合は、self.p_userID を ID に設定し、セグエを開始します。

ルックアップを実行して、 self.p_userIDprepareForSegueから userInfo 辞書を取得して C に渡し、次に self.p_userID を nil に設定する必要があります。または (より良い) self.p_userID を C に渡し、C でルックアップを実行します (別のモデル ソース オブジェクトがあると仮定します)。何をするにしても、self.p_userIDA を離れるときは必ず nil に設定して、不要なセグエを自動トリガーしないようにしてください! おそらく、「viewWillDisappear」でもゼロにします。

于 2013-02-04T17:25:55.983 に答える