Well .. It seems to me that you came across a mistake. This should be reported via apples bugreporter ( here ).
I did a simple practical work, but remember what works . This will work, but you may have to view it if you have / add other controls to the tableView. It should be safe to use (not acting randomly), and it is not the ugliest of jobs, so I think itβs normal to use in the release. I downloaded the same project with the fix here , and you can just go and download it and you will probably understand what I did. I will explain (in detail) what I actually thought and did here, in case the download links will die in the future:
Train of thought:
As simalone also said, the problem is that when hidesBottomBarWhenPushed set to YES , then it is called by an additional viewDidLayoutSubviews , which somehow resets the current state. We need to redefine viewDidLayoutSubviews and check if we put subviews, because we come from ViewController , or if it is a normal call. When we establish that the call is valid because we are returning from the ViewController , we need to hide the search bar (only if it was hidden earlier).
When we return from the ViewController , three calls are made to the viewDidLayoutSubviews in the TableViewController . I assume the first one is for the tableView , and it seems that the second call is the "for" (or rather, out of) the tabBar. This second is the one that moves the searchBar down. I do not know what the third challenge is, but we can ignore it.
So, now there are three things that need to be checked inside viewDidLayoutSubviews : we need to check if we are returning from the ViewController , we need to check if the SearchBar is hidden before we click (if it should now hide), and we need to check that this is the second call for this method.
Primarily.
In TableViewController I added the @property BOOL backPush; in the header ( .h ) is the file. Now I need to change this variable from ViewController .
In the ViewController , I set this:
#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]; } }
In the above code, when the view disappears (IE pushing forward, backward, closing, whatever), I check if we disappear because it has been removed from the parent. If so (this is when the back button is called), I check to see if the top-level controller now has the current class of the TableViewController class, which also exists if we return. Then I set the backPush property to YES . This is the only thing we need in the ViewController .
Now, in the TableViewController . I added a counter next to your row count:
@interface TableViewController () { NSInteger _rows; int count; }
This is to keep track of how many calls were made to viewDidLayoutSubviews later. I set count = 0; in viewDidLoad .
Now to the magic:
-(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; } }
The first if statement wants any of these situations:
backPush YES , count is 0 , and searchBar is already hidden.backPush is YES , count is 1 , and the search bar is visible.
If 1. is true, then we increase count by 1. If 2. is true, then 1. has already happened, and now we know that we are in the second round of viewDidLayout.. when we return from VC And that searchBar WAS is hidden (because happened 1.), but now is not hidden. This probably happens in a super-method or something like that. Now we can finally click SearchBar again. I also reset the count and set backPush back to NO .
else if also very important. It checks if there is count 0 or 1 , or if the keyboard is displayed in the search bar. If count is 0 or 1 when it reaches here, it means that the first if statement was hit, for example, that searchBar was not hidden or that it was scrolling far up.
(When I think about it, the else-if should check if backPush YES . Now it sets these variables many times)
Let me know if you find a better way!