11

I have an issue with a search bar that behaves in a strange way when it becomes a firstResponder and when it resigns.

The search bar is added as the header of a table view

self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, 44.0f)];
self.searchBar.translucent = NO;
self.searchBar.barTintColor = [UIColor grayColor];
self.tableView.tableHeaderView = self.searchBar;

self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar
                                                          contentsController:self];
self.searchController.searchResultsDataSource = self;

The view controller is set a left panel of JASidePanelController and it hides the center panel when the keyboard shows or hides :

- (void)keyboardWillAppear:(NSNotification *)note
{
    [self.sidePanelController setCenterPanelHidden:YES
                                          animated:YES
                                          duration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    self.searchBar.showsCancelButton = YES;
}

- (void)keyboardWillDisappear:(NSNotification *)note
{
    [self.sidePanelController setCenterPanelHidden:NO
                                          animated:YES
                                          duration:[[note.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
    self.searchBar.showsCancelButton = NO;
}

Normal state Normal state

When the search bar becomes a firstResponder it either moves about a point up or point down randomly

Point up Point down



And When the search bar resigns it animates up to reach the window origin and then back to its natural frame

Stretching up

Reaching origin

Here is a sample project reproducing the bug.

EDIT :

As per @kwylez suggestion, the unwanted animation that the search bar makes when it resigns can be avoided by:

self.searchBar.clipsToBounds = YES;
Moxy
  • 4,162
  • 2
  • 30
  • 49
  • Adding your searchbar as a subview of the viewcontroller's view, instead of as the tableView's tableHeader fixes the up/down motion, if it doesn't have to be the tableHeader. – Joseph Chen Jan 16 '14 at 08:47
  • That's true but I have content behind the table view that needs to show when the user scrolls... I may fall back to solution though if I don't find anything. – Moxy Jan 16 '14 at 08:51
  • try this self.searchBar.showsCancelButton = NO;[self.searchBar sizeToFit]; – Chamira Fernando Jan 16 '14 at 16:09

3 Answers3

8

I solved this issue by creating a UIView with ClipBounds sets to YES and then add subview the searchbar inside it. Then include it in tableview header. its working now.

Thanks

Muhammad Ahsan
  • 297
  • 2
  • 15
0

You initialize a search display controller with a search bar and a view controller responsible for managing the data to be searched. When the user starts a search, the search display controller superimposes the search interface over the original view controller’s view and shows the search results in its table view.

customized your searchbar view

Fixed - UISearchBar-bug-master

codercat
  • 22,873
  • 9
  • 61
  • 85
  • You only changed the colors (I hope I'm not missing something) The gap still shows the table view's background (once every 2 times) before typing – Moxy Jan 16 '14 at 15:26
  • search display controller superimposes the search interface over the original view controller’s view. Read apple doc – codercat Jan 16 '14 at 15:29
  • 1
    I know but it shouldn't leave that gap. It doesn't in iOS 6. `UISearchDisplayController` has many bugs in iOS 7 but one needs to use it. I'm looking for a solution to change its behavior for this case. I appreciate the effort and would be more than happy to accept an answer (and even award another bounty as this one is already ending) but in this case stating where the problem is does not solve it. – Moxy Jan 16 '14 at 16:08
-1

I traced the issue to the function "_layoutSidePanels" in the JASidePanelController.

In your app delegate, I commented out the following code and it seems to fix the grey view growing and shrinking.

rootViewController.shouldResizeLeftPanel = YES;

If you follow the code through, when the searchbar is selected you call setCenterPanelHidden, which subsequently calls _layoutSidePanels, which runs the following code:

if (self.leftPanel.isViewLoaded) {
    CGRect frame = self.leftPanelContainer.bounds;
    if (self.shouldResizeLeftPanel) {
        frame.size.width = self.leftVisibleWidth;
    }
    self.leftPanel.view.frame = frame;
}

Changing the frame of the sidepanel seems to be the cause, and as I said commenting that code out fixes the issue on my end.

Edit: Also at first it seemed like the search bar was moving up and down a point, but upon further inspection it appears that it is always slightly underneath the navigation bar, but you don't notice it until you select the searchbar and the rest of the view "greys" out, so that little space that was white between the blue nav bar and light grey search bar becomes dark grey like the rest of the tableview below.

Edit #2: Took me a while, but I managed to figure out where the heck that grey mask was coming from. Your UISearchDisplayController is what is responsible for the greyish background that appears when the search bar becomes first responder, and when I removed the following two lines of code the issue you were seeing went away:

self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.searchController.searchResultsDataSource = self;

Doing this was just to demonstrate the cause of the issue, but removing those lines of code disable whatever functionality you were going to gain from using the search display controller. I don't know exactly what you're hoping to do, so I can't really give you any advice about how to proceed, but hopefully I've pointed you in the right direction as to the causes!

Mike
  • 9,765
  • 5
  • 34
  • 59
  • 1
    The issue as you stated is definitely `UISearchDisplayController` that has this bug even in Apple's sample code. The animation "conflict" with JASidePanels is resolved by clipping to bounds. – Moxy Jan 13 '14 at 16:57
  • If my answer helped at all, approving it would be greatly appreciated! :) – Mike Jan 13 '14 at 17:09
  • Your answer is pointing where the problem is but not solving it. I had the clip to bounds solution before you answered (check my edit). I'd be more than happy to approve yours if you changed it and it solves the problem :) – Moxy Jan 13 '14 at 17:44
  • 1
    If the problem, as you stated, is an iOS bug and not a bug with your code, I'd think you would have to either live with it until apple fixes it, or get rid of the UISearchDisplayController and implement your own searchbar functionality. – Mike Jan 13 '14 at 18:04