4

I'm working on an application that has a view hierarchy that is very similar to Apple's Music or iPod aps. It has a UITabBarController containing UINavigationControllers presenting UITableViews that eventually lead to a UIViewController that sets hidesBottomBarWhenPushed to YES in its designated initializer (to hide the UITabBar). The previous UITableViews all have a UISearchBar in their tableHeaderView that I move out of sight in viewWillAppear:.

The UISearch normally remains hidden until pulled down except when backing out of the UIView to a short UITableView. It remains hidden through the UITableView's viewWillAppear: and viewDidAppear: methods and the UIView's viewWillDisappear: and viewDidDisappear: methods and then finally pops down of its own accord. If I comment out self.hidesBottomBarWhenPushed = YES; in the UIView the UISearchBar stays hidden when backing out of that view.

What is causing the UITableView to reveal the UISearchBar after I have hidden it? Is there a delegate method higher up in the view hierarchy that I can use to prevent it from happening?


Update I've created a simple project with the minimum amount of code needed to reproduce the problem. Download PushySearchBar.zip. (Sorry, I had a mod_rewrite rule preventing downloads from third-party domains. I've added Stack Overflow to the whitelist. Download should work now.)

Shaun Inman
  • 1,968
  • 1
  • 19
  • 28

2 Answers2

1

Does the UISearchBar have text in it when backing out of the UIViewController? Seems plausible that this might cause it to be displayed by default.

EDIT: (adding below comment to body of answer for easier scanning / finding, plus adding some explanation.)

Duplicate your viewWillAppear: method body in viewDidAppear: in SearchableTableViewController. This fixes the issue in my testing.

Basically, all this does is ensure that the offset is set correctly on either side of the navigation animation.

Brad
  • 655
  • 2
  • 7
  • 13
  • Nope. Just the default "Search" placeholder that doesn't cause it to pop-down on any of the preceding views. – Shaun Inman Dec 06 '10 at 14:33
  • Another theory: Could the `UITableView` be resizing itself to as the `UITabView` is being slid back in, causing the `contentOffset` to change? That seems far fetched, but if you could `NSLog` or `po` the offset before and after, you might find the culprit. – Brad Dec 06 '10 at 16:16
  • It's possible but the change is happening after all of the view lifecycle methods fire so part of the problem is figuring out where to place the `NSLog()` for the "after" check. – Shaun Inman Dec 06 '10 at 16:45
  • 1
    You could subclass `UITableView` and override `setContentOffset:` (and `setContentOffset:animated:`) to add a breakpoint or `NSLog`, then use that tableView in place of the default. This would allow you to see the backtrace. – Brad Dec 06 '10 at 17:26
  • Here you go: Duplicate your `viewWillAppear:` method body in `viewDidAppear:` in `SearchableTableViewController`. This fixes the issue in my testing. – Brad Dec 06 '10 at 17:37
  • Good call. Looks like the private `[UIScrollView(Static) _adjustContentOffsetIfNecessary]` is the last method to call `setContentOffset:` before the jump occurs. Looks like it's sending a `-0.0` as the y value which after initial testing seems to be a unique value that I can use to return from the method without calling the super to eliminate the problem. I might have my answer. – Shaun Inman Dec 06 '10 at 17:56
  • Nope. That breaks tapping the status bar to scroll to top. – Shaun Inman Dec 06 '10 at 18:02
0

Shaun - I'm still learning Objective-C too so I might be off on this, but I think the issue is that ViewWillAppear: fires once when you get to the SearchableTableView 3 view, and then when you try to go backwards from Terminal to SearchableTableView 3 it's not firing again. I duplicated the code in ViewWillAppear: and put it in ViewDidAppear: and the search bar appears to be hiding properly.

UPDATE: This post seems to verify the above and offer cleaner solutions: iPhone viewWillAppear not firing

Community
  • 1
  • 1
Jon Friskics
  • 292
  • 2
  • 9
  • Thanks Jon but the problem isn't that the UITableView's `viewWillAppear:` isn't firing when backing out of the UIView. The problem is that some event after that method fires is forcing its contentOffset back to `(0,0)` and causing the UISearchBar (which *is* moved offscreen successfully in the returning UITableView's `viewWillAppear:`) to pop back into view. – Shaun Inman Dec 06 '10 at 16:42