我的UI结构如下:UITabBarController
( TBC )-> UINavigationController
( NC )-> UITableViewController
( TVC )
(为简化示例,可以说 TBC 的viewControllers
数组上只有一个 Controller - NC )
我的 TVC 将UISearchBar
作为其表标题,当 TVC 出现时,我通过设置表格 View 内容偏移量来将搜索栏隐藏在 NC 导航栏下方。
当用户点击 TVC 中的单元格时,将推另一个 View Controller ( VC ),并使用VC.hidesBottomBarWhenPushed = YES;
隐藏选项卡栏
现在有一个非常烦人的行为,我不知道该如何解决:
当用户将后退按钮从 VC 返回到 TVC 时,即使在按下 VC 之前将其隐藏(在导航栏下方),搜索栏也会跳转为可见。
仅当 TVC 没有足够的行来填充屏幕时,才会发生这种效果,就像在屏幕上有一个位置时,搜索栏一样,它本身必须可见。但它看起来确实很糟糕而且有故障。
我上传了一个simple project来演示问题,它的结构与我在问题中描述的结构相同。
为了方便起见,我添加了两个栏按钮,“隐藏栏”按钮为您隐藏了搜索栏,而“切换计数”按钮切换了表格 View 的行数,以证明仅当项目很少时才会出现此问题。
最佳答案
好吧..在我看来,您偶然发现了一个错误。应该通过apples bugreporter(here)报告。
我已经做了一个简单的解决方法,但请记住是解决方法。这将起作用,但是如果您向tableView中添加了其他控件,则可能必须对其进行检查。它应该安全使用(不能随机执行),并且不是最丑陋的解决方法,因此我认为在发行版中使用是可以的。我已经上传了具有修复程序here 的同一个项目,您可以继续下载该文件,您可能会了解我的所作所为。如果将来下载链接消失了,我将在这里(非常详细地)解释我实际上的想法和所做的事情:
思路:
就像simalone所说的那样,问题在于,当hidesBottomBarWhenPushed
设置为YES
时,它将调用附加的viewDidLayoutSubviews
,从而以某种方式重置您的当前状态。我们需要重写viewDidLayoutSubviews
,并检查是否要布置 subview ,因为我们来自ViewController
,还是只是常规调用。当我们确定调用确实是因为我们要从ViewController
返回时,我们需要隐藏搜索栏(仅当它之前被隐藏时)。
当我们从ViewController
返回时,在viewDidLayoutSubviews
中对TableViewController
进行了三个调用。我猜第一个是tableView
,而且似乎第二个调用是“for”(或者更确切地说是来自)tabBar。第二个是向下移动searchBar
的代码。我不知道第三个电话是什么,但我们可以忽略它。
因此,现在我们需要检查viewDidLayoutSubviews
内部的三件事:我们需要检查是否从ViewController
返回,我们需要在按下pushBar之前检查searchBar是否被隐藏(如果应该现在被隐藏),并且需要检查这是此方法的第二个调用。
首先是第一件事。
在TableViewController
中,我向头文件(@property BOOL backPush;
)文件添加了一个属性.h
。现在,我需要从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];
}
}
在上面的代码中,当 View 消失时(即向前,向后,关闭,前进等),我正在检查是否要消失,因为它已从父 View 中删除。如果是(调用后退按钮时是这种情况),则我检查现在-当前的顶部 View Controller 是否为
TableViewController
类,如果我们返回,也是如此。然后,将属性backPush
设置为YES
。那是我们唯一需要的ViewController
。现在,到
TableViewController
。我在您的行数旁边添加了一个计数器:@interface TableViewController () {
NSInteger _rows;
int count;
}
这是为了跟踪以后已对
viewDidLayoutSubviews
进行了多少次调用。我在count = 0;
中设置了viewDidLoad
。现在开始魔术:
-(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为true,那么我们将
count
加1。如果2.是true,则1.已经发生,现在我们知道从 VC 返回时,我们处于
viewDidLayout..
的第二轮,并且searchBar WAS 是隐藏的(因为1.发生了),但是现在没有隐藏。它可能发生在 super 方法之类的东西中。现在,我们终于可以再次将searchBar推出了。我还重置了count并将backPush设置回
NO
。else if
也非常重要。它检查count
是0
还是1
,或者searchBar是否显示键盘。如果count到达此处时是0
或1
,则表示第一个if语句失败,例如searchBar未隐藏或滚动到更高的位置。(当我想到它时,else-if应该也检查
backPush
是否也是YES
。现在它反复设置这些变量)如果您找到更好的方法,请告诉我!
关于ios - 如果按下的 Controller 隐藏了标签栏,则UISearchBar会跳转,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22232538/