看起来我在navigationController pushViewController方法中发现了一个错误。为了重新创建它,我采用了样本主详细信息项目并对-didSelectRow:
方法进行了一些更改:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailViewController* view = [self.storyboard instantiateViewControllerWithIdentifier: @"view"];
NSDate *object = _objects[indexPath.row];
[view setDetailItem:object];
[self.detailViewController.navigationController pushViewController:view animated:YES];
}
我还将详细视图的故事板ID更改为“查看”。这是发生的事情:
当慢慢选择任何主人的行时(当推动动画完成时),它可以正常工作:
如果在动画仍然显示时选择任何行,则详细视图将变为非活动状态(显示在错误之前使用push方法调用的最后一行),并且只有导航栏显示新动画的推送动画视图:
当发生这种情况时,您会在调试器输出中收到一些警告:
Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
nested push animation can result in corrupted navigation bar
Unbalanced calls to begin/end appearance transitions for <DetailViewController: 0x8a6e070>.
这是令人讨厌的部分:如果你回到详细视图的导航栏然后在Master的tableview中选择一个不同的行,或者在详细信息中返回两次应用程序崩溃
Can't add self as subview
但如果你在ios6上运行相同的代码,它可以正常运行。
当前解决方案:
用动画调用方法:NO似乎没有任何问题,显然没有推动画。
另一个解决方案是在Master中设置一个布尔值,在调用push方法时将其设置为false,并从Detail in Detail的viewDidAppear中将其设置为true。这样,您可以在调用push方法时检查该值。缺点:如果您尝试快速选择同一行,tableView可能会显得滞后,如果您快速选择另一行然后它不会显示在详细信息中但它将在主表视图中被选中并突出显示,您可以保存所选行的索引并更改代码中的选择,但这会导致闪烁的行突出显示。
这两个解决方案都涉及一些妥协,所以我想找到另一种处理方法。有没有更好的解决方案?
答案 0 :(得分:5)
经过一些测试后,在ios6中,当一个tableview单元被选中并且push被调用时,tableview会将.allowsSelection
设置为NO
,直到推送结束。
通过在.allowsSelection
中的推送方法之后将NO
设置为didSelectRowAtIndexPath:
并在详细信息视图的didAppear:
方法中进行回调,可以在ios7中轻松复制此内容我们在主视图中将tableview的.allowsSelection
设置为YES
。
虽然这种方法非常好但我发现在一个接一个地快速选择两个不同的单元格时会发现它有点烦人,第二个单元格会被忽略。
所以我设置了如果在推动动画尚未结束时选择了另一个单元格,我将保存对新视图的引用,并在第一个动画结束后立即推送它。通过这样做,tableView在我看来似乎更具响应性。
答案 1 :(得分:1)
你背后的原因是推动一个视图控制器,而另一个没有被完全推动(日志已警告你这样做了)。
推送动画应该花费大约0.4秒,因此用户必须足够快以在0.4秒内点击另一行,是的,这是适用的,但不是正常行为。
您可以使用-didSelectRow:
方法中的以下代码将动画时间编辑为小于0.4秒(可能是0.1或0.2):
DetailViewController* view = [self.storyboard instantiateViewControllerWithIdentifier: @"view"];
NSDate *object = _objects[indexPath.row];
[view setDetailItem:object];
[UIView beginAnimations:@"ShowDetails" context: nil];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.2];
[self.detailViewController.navigationController pushViewController:view animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
希望有所帮助:)