私のアプリには次のビューコントローラーが組み込まれています。提示するコントローラーは「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")のセグエが表示されています。どちらもプッシュセグエです:
よろしくお願いします!