如果推送控制器隐藏标签栏,UISearchBar会跳转

Eya*_*yal 6 iphone objective-c uitabbarcontroller uisearchbar ios

我的UI结构如下:

UITabBarController(TBC) - > UINavigationController(NC) - > UITableViewController(TVC)

(为了简化示例,我们可以说TBC在其viewControllers阵列上只有一个控制器--NC)

我的TVC具有UISearchBar表格标题,当TVC出现时,我通过设置表格视图内容偏移量隐藏NC导航栏下方的搜索栏.

当用户点击TVC中的一个单元时,按下另一个视图控制器(VC)并隐藏标签栏VC.hidesBottomBarWhenPushed = YES;

现在有一个非常令人讨厌的行为,我不知道如何解决:
当用户轻按后退按钮VCTVC,搜索栏跳转到是可见的,即使它是隐藏的(导航栏下方)的前VC是推.

仅当TVC没有足够的行来填充屏幕时才会出现此效果,如果屏幕上有某个位置,它就像搜索栏一样强制自己可见.但它真的看起来很糟糕和马车.

我上传了一个演示问题的简单项目,它与我在问题中描述的结构相同.
为方便起见,我添加了两个小节按钮,"隐藏栏"按钮为您隐藏搜索栏,"切换计数"按钮切换表格视图行计数,以证明只有少数项目才会出现问题.

Sti*_*Sti 7

好吧..在我看来你偶然发现了一个错误.它应该通过apples bugreporter(这里)报告.

我做了一个简单易懂的童话工作,但请记住,这一个解决方法.这将有效,但如果您有/向tableView添加其他控件,则可能需要查看它.它应该是安全的(不是随意的),并且它不是最丑陋的解决方法,所以我认为在发布中使用它很好.我已经在这里上传了相同的项目,你可以继续下载它,你可能会理解我做了什么.我将解释(非常详细)我在这里实际思考和完成的事情,以防下载链接在将来死亡:

思路:

正如simalone所说,问题是当hidesBottomBarWhenPushed设置为YES,然后它会调用一个额外的viewDidLayoutSubviews,以某种方式重置您当前的状态.我们需要覆盖viewDidLayoutSubviews,并检查我们是否正在布置子视图,因为我们来自ViewController,或者它只是一个普通的电话.当我们确定调用确实是因为我们正在返回时ViewController,我们需要隐藏搜索栏(仅当它被隐藏之前).

当我们从返回ViewController,三个电话都是由viewDidLayoutSubviewsTableViewController.我猜的第一个是for tableView,而且似乎第二个调用是'for'(或者更确切地说来自)tabBar.第二个是searchBar向下移动的那个.我不知道第三个电话是什么,但我们可以忽略它.

所以现在我们需要检查三件事情viewDidLayoutSubviews:我们需要检查一下是否正在返回ViewController,我们需要在推送之前检查searchBar是否被隐藏(如果它现在应该被隐藏),我们需要检查它是否是所述第二调用此方法.

首先要做的事情.

TableViewController,我向@property BOOL backPush;header(.h)-file 添加了一个属性.现在我需要更改此变量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];
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,当视图消失时(IE向前推,向后,关闭,等等),我正在检查我们是否正在消失,因为它已从父节点中删除.如果是(当调用后退按钮时),我检查现在的当前顶视图控制器是否属于类TableViewController,如果我们返回它也是如此.然后我将属性设置backPushYES.这是我们唯一需要的东西ViewController.

现在,到了TableViewController.我在你的行数旁边添加了一个计数器:

@interface TableViewController () {
    NSInteger _rows;
    int count;
}
Run Code Online (Sandbox Code Playgroud)

这是为了跟踪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;
    }
}
Run Code Online (Sandbox Code Playgroud)

第一个if语句需要以下任何一种情况:

  1. backPushis YES,countis 0和searchBar已经被隐藏了.
  2. backPushis YES,countis 1和searchBar是可见的.

1.如果是真的,那么我们增加count1.如果2是真的,那么1已经发生了,我们现在知道我们是在第二轮的viewDidLayout..时候,我们从回来VC和搜索栏WAS隐藏(因为1.发生了)但现在并没有隐藏.它可能发生在超级方法或其他东西.现在我们终于可以再次推出searchBar了.我也重置计数并设置backPush回NO.

else if也很重要.它检查是否count0或者1,或者searchBar是否显示键盘.如果count是0或者1到达这里,则意味着第一个if语句失败,例如,searchBar没有被隐藏,或者它被向远处滚动.

(当我想到它时,else-if应该检查是否backPush也是YES如此.现在它重复设置这些变量)

如果您找到更好的方法,请告诉我!


小智 1

尝试设置为 TVC

 self.automaticallyAdjustsScrollViewInsets = NO
Run Code Online (Sandbox Code Playgroud)