好的.. 在我看来你偶然发现了一个错误。应该通过 apples bugreporter (here) 报告。
我做了一个简单的变通办法,但请记住,它是变通办法。这将起作用,但如果您有/向 tableView 添加其他控件,您可能需要查看它。它应该是安全的(不是随机行为),而且它不是最丑陋的变通方法,所以我认为在发布中使用它是可以的。我已经上传了相同的项目,修复了here,你可以继续下载它,你可能会明白我做了什么。我将(非常详细地)解释我在这里的实际想法和做法,以防下载链接将来失效:
思路:
正如 simalone 所说,问题是当 hidesBottomBarWhenPushed 设置为 YES 时,它会调用一个额外的 viewDidLayoutSubviews 以某种方式重置您当前的状态。我们需要覆盖viewDidLayoutSubviews,并检查我们是否正在布置子视图因为我们来自ViewController,或者这只是一个常规调用。当我们确定调用确实是因为我们从ViewController 返回时,我们需要隐藏搜索栏(仅当它之前隐藏时)。
当我们从ViewController 返回时,在TableViewController 中对viewDidLayoutSubviews 进行了三个调用。我猜第一个是为tableView,似乎第二个调用是'for'(或者更确切地说是来自)tabBar。这第二个是将searchBar 向下移动的那个。我不知道第三个电话是什么,但我们可以忽略它。
所以现在我们需要在viewDidLayoutSubviews 中检查三件事:我们需要检查我们是否从ViewController 返回,我们需要检查 searchBar 在我们推送之前是否隐藏(如果应该现在隐藏),我们需要检查它是否是对这个方法的第二次调用。
首先要做的事情。
在TableViewController 中,我在标题(.h) 文件中添加了一个属性@property BOOL backPush;。现在我需要从ViewController 更改这个变量。
在ViewController,我放了这个:
#import "TableViewController"
...
-(void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if(self.isMovingFromParentViewController)
{
if([self.navigationController.topViewController isKindOfClass:[TableViewController class]])
[((TableViewController*)self.navigationController.topViewController) setBackPush:YES];
}
}
在上面的代码中,当视图消失(即向前、向后、关闭等等)时,我正在检查我们是否因为它已从父视图中删除而消失。如果是(调用后退按钮时),我检查 now-current 顶视图控制器是否属于 TableViewController 类,如果我们返回,它也是。然后我将属性backPush 设置为YES。这是我们在ViewController 中唯一需要的。
现在,到TableViewController。我在您的行数旁边添加了一个计数器:
@interface TableViewController () {
NSInteger _rows;
int count;
}
这是为了跟踪以后有多少次调用viewDidLayoutSubviews。我在viewDidLoad 中设置了count = 0;。
现在开始魔术:
-(void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
if((self.backPush && count == 0 && self.tableView.contentOffset.y ==
self.tableView.tableHeaderView.frame.size.height) ||
(self.backPush && count == 1 &&
self.tableView.contentOffset.y == 0))
{
if(count == 0)
count++;
else
{
count = 0;
self.backPush = NO;
[self hideSearchBar];
}
}
else if((count == 0 || count == 1) || self.tableView.tableHeaderView.isFirstResponder)
{
count = 0;
self.backPush = NO;
}
}
第一个 if 语句需要以下任何一种情况:
-
backPush 是 YES,count 是 0,并且 searchBar 已经隐藏。
-
backPush 是 YES,count 是 1,并且 searchBar 是可见的。
如果 1. 为真,那么我们将 count 加 1。
如果 2. 是真的,那么 1. 已经发生了,我们现在知道当我们从 VC 回来时我们正处于第二轮 viewDidLayout.. 并且 searchBar WAS 隐藏(因为 1. 发生了)但现在没有隐藏。它可能发生在超级方法或其他东西中。
现在我们终于可以再次推出 searchBar 了。我还重置了计数并将 backPush 设置回NO。
else if 也很重要。它检查count 是0 还是1,或者搜索栏是否显示键盘。如果 count 到达这里时是 0 或 1,则意味着第一个 if 语句失败,例如 searchBar 没有隐藏,或者它被向上滚动得很远。
(当我想到它时,else-if 应该检查backPush 是否也是YES。现在它重复设置这些变量)
如果你找到更好的方法,请告诉我!