Ios 协调视图控制器时出现问题
我的应用程序中内置了以下视图控制器。演示控制器是“PatientSelectViewController”(我们称之为控制器A),它允许在文本字段中手动输入患者ID或按下“扫描条形码”按钮,该按钮将执行到另一个视图控制器的切换,即“BarcodeScanViewController”(我们称之为控制器B) 当B扫描完条形码并返回一个结果(患者ID)时,我通知演示视图控制器(a),a负责在数据库中查找ID。此时应解除控制器B。如果找到ID,那么我们将转换到第三个视图控制器-“PatientConfigrmViewController”(我们称之为C)。但是,如果找不到ID,我希望弹出一条消息,上面写着“是”,然后再次转到控制器B再次扫描条形码 类似地,如果用户决定在文本字段中手动输入ID而不是扫描它,那么成功的ID会将我带到控制器C,而不成功的ID会弹出一条消息,并留在控制器a中进行另一次尝试 我还希望控制器嵌入到导航控制器中,以便始终具有选项卡栏按钮,将我带回上一个视图控制器。例如,我将有一个tabbar按钮从B或C返回a。理想情况下,如果我在成功的条形码扫描后到达C,我希望tabbar按钮将我带回到B,而不是a如果用户决定不想确认此ID,则可能需要重新扫描条形码。但这并不重要 由于某种原因,我在实现这一点上遇到了困难。下面是一个错误行为的例子:我先打电话给a,然后打电话给B(扫描条形码),然后扫描数据库中的条形码。这会正确地将我带到C,并显示患者信息。但后来我决定使用tabbar按钮“输入患者ID”返回到A,然后我再次按下“扫描条形码”按钮,再次像以前一样扫描相同的条形码,但这次没有成功过渡到C,我得到了这个屏幕-注意这个错误的tabbar!它必须同时显示“确认ID”和“输入患者ID”,然后按钮返回登录(这是首先调用A的控制器)和“扫描条形码”-即控制器B,就好像它以前从未弹出过一样! 这可能在2次、3次或更多成功扫描后随机发生。日志将显示以下内容: 嵌套推送动画可能导致导航栏损坏 对开始/结束外观转换的不平衡调用 . 完成导航 处于意外状态的转换。导航栏子视图树可能 腐败 下面是我如何实现它的: 在视图控制器A中:Ios 协调视图控制器时出现问题,ios,objective-c,uiviewcontroller,delegation,Ios,Objective C,Uiviewcontroller,Delegation,我的应用程序中内置了以下视图控制器。演示控制器是“PatientSelectViewController”(我们称之为控制器A),它允许在文本字段中手动输入患者ID或按下“扫描条形码”按钮,该按钮将执行到另一个视图控制器的切换,即“BarcodeScanViewController”(我们称之为控制器B) 当B扫描完条形码并返回一个结果(患者ID)时,我通知演示视图控制器(a),a负责在数据库中查找ID。此时应解除控制器B。如果找到ID,那么我们将转换到第三个视图控制器-“PatientConf
-(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
}
}
- (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];
}
接收条形码扫描结果的委托方法(仍在控制器a中):
在数据库中查找ID的方法(仍在A中):
为了完整起见,在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(“条形码扫描”)和a到C(“确认”)的顺序可见。两者都是推送序列:
提前多谢 您不会说您当前是否正在使用导航控制器和推送序列,或者使用模式序列 在这里: 第一个适用于从推送序列返回,第二个适用于模式/呈现序列。当您在导航控制器中使用“后退”按钮时,推送返回方法实际上就是这样 更新 我认为你需要稍微理清你的导航方法。我的建议
- 在B中,有一个委托方法
- 检查患者ID
- 如果很好,请在
- 将布尔成功/失败返回到B。
_
- 根据这一结果,或者:
- 将自己弹出(您可以直接在B中使用
)或[self.navigationController popViewController]
- 在B中调出您的警报。考虑到您在B中有一个后退按钮和(可能)一个重新扫描按钮,您的警报可能不需要显示任何选项
- 将自己弹出(您可以直接在B中使用
- (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;
}
}
(仅当您在B中设置self.p_userID时,才会发生此性能检查)
输入的用户标识逻辑更简单。再次检查患者id。如果患者id不在,则在A中弹出警报(同样,您不需要显示选项,因为所有导航选项都可以在没有警报的情况下使用)。如果有,将self.p_userID设置为ID并启动segue
在
prepareForSegue
中,您应该进行查找,从self.p_userID获取userInfo字典,并将其传递给C,然后将self.p_userID设置为nil。或者(更好)只需将self.p_userID传递给C并在C中进行查找(假设您有一个单独的模型源对象)。无论您做什么,请确保在离开时将self.p_userID
设置为nil,这样您就不会自动触发您不想要的序列!也许在“视图”中将其归零也会消失。好的,我想部分回答我自己的问题。
即使在执行了上面的建议后,我的麻烦依然存在,甚至成倍增加(关于这些问题的一些细节,请参阅我在讨论帖中的评论)
然而,通过一些更改,我在谷歌上搜索了我得到的日志消息:“嵌套推送动画可能导致导航栏损坏”,最后阅读了以下答案:,这表明我的问题是使用了
[self.navigationController popViewControllerAnimated:YES];
这是设置为“是”的动画。一旦我将其设置为NO,tabbar的问题就消失了(一些小问题仍然存在,我希望很快解决它们)。这真的很奇怪——对m来说,这更像是一个bug,而不是一个特性
- (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;
}
}
[self.navigationController popViewControllerAnimated:YES];