4

This might be a bug in iOS 7: I used storyboard to drag in Search Bar and Search Display Controller in my tableview controller. The background color of my tableview is altered after that. I am using an example from AppCoda's "how-to-add-search-bar-uitableview" to demo this issue. I only changed the example code with 1-line add-on in ViewDidLoad:

   [_tableView setBackgroundColor:[UIColor blackColor]];

See my screenshots here:

  1. The bottom of the tableview has already changed to black: enter image description here

  2. But the top stays as gray though tableview's background was set to black: enter image description here This only happens when I drag in "Search Bar and Search Display Controller". If I remove the "Search Display Controller" from storyboard, it's all good.

Kumar KL
  • 15,315
  • 9
  • 38
  • 60
  • I was working on this all day. I tried with dragging in only the search bar and there is no problem. See screenshot here (https://www.dropbox.com/s/dnlqajb3wz9vdvo/2014-04-11%2022.45.40.png). However, anytime I add SearchDisplayController even programmatically, the issue will be able to be reproduced. – Tong Bruce Yang Apr 12 '14 at 05:47
  • If you want to reproduce this bug, just checkout the example I used here "http://www.appcoda.com/how-to-add-search-bar-uitableview/" with tableview's background color change. – Tong Bruce Yang Apr 12 '14 at 05:50

3 Answers3

4

When using a UISearchDisplayController in a UITableViewController, it is very important to remember that you are dealing with two table views.

So when you drag a "Search Bar and Search Display Controller" into a UITableView (and assuming you are doing this drag in a UIStoryboard), you are actually added another UITableView that, when activated, must be managed by code in your UITableViewController file in the same manner as any other UITableView.

Consider this:

The UITableView that represents the complete data set can be called using self.tableView (or as you have written, the synthesised _tableView).

The UITableView that represents the filtered data set (filtered using your search criteria) can be called using self.searchDisplayController.searchResultsTableView

If you'd like both your default UITableView and search UITableView background colour to display a black colour, I can suggest this code (works in a TVC in my app)...

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.tableView setBackgroundView:nil];
    [self.tableView setBackgroundColor:[UIColor blackColor]];

    [self.searchDisplayController.searchResultsTableView setBackgroundView:nil];
    [self.searchDisplayController.searchResultsTableView setBackgroundColor:[UIColor blackColor]];
}

...

UPDATE

Now that I have finished my long-winded lecture, I agree that there is in fact a "bug" of sorts in Xcode. If you delete the original UISearchBar and then add a new one to a UITableViewController, before you connect it, do a Build & Run. A black background is visible below and above the table view. It is only after you set the UISearchBar as an outlet for the UISearchDisplayController that the black background is "replaced" with a grey background.

So the solution...

With thanks to Olof's answer to Different background colors for the top and bottom of a UITableView.

REPLACE the code I have written above with this code, at the end of your viewDidLoad method:

- (void)viewDidLoad {
    [super viewDidLoad];

    ...<other code>...

    CGRect frame = self.tableView.bounds;
    frame.origin.y = -frame.size.height;
    UIView* viewBackgroundBlack = [[UIView alloc] initWithFrame:frame];
    [viewBackgroundBlack setBackgroundColor:[UIColor blackColor]];
    [self.tableView addSubview:viewBackgroundBlack];

    [self.tableView setBackgroundView:nil];
    [self.tableView setBackgroundColor:[UIColor blackColor]];

    [self.searchDisplayController.searchResultsTableView setBackgroundView:nil];
    [self.searchDisplayController.searchResultsTableView setBackgroundColor:[UIColor blackColor]];
}
Community
  • 1
  • 1
andrewbuilder
  • 3,629
  • 2
  • 24
  • 46
  • I tried with that but it doesn't seem to work. Wonder if you have tried out and make it work. Let me know where you put this code. – Tong Bruce Yang Apr 12 '14 at 06:10
  • Read this https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableView/backgroundView – andrewbuilder Apr 12 '14 at 07:31
  • Include the line '[searchTableView setBackgroundView:nil];' – andrewbuilder Apr 12 '14 at 07:32
  • Also the URL for the AppCode tutorial you refer to appears to be no longer valid - try this instead - http://www.appcoda.com/search-bar-tutorial-ios7/ – andrewbuilder Apr 12 '14 at 07:38
  • Unfortunately, I tried that but it still doesn't work. I put these 4 lines in ViewDidLoad but there is no change: [self.tableView setBackgroundColor:[UIColor blackColor]]; UITableView *searchTableView = self.searchDisplayController.searchResultsTableView; [searchTableView setBackgroundColor:[UIColor blackColor]]; [searchTableView setBackgroundView:nil]; – Tong Bruce Yang Apr 12 '14 at 08:36
  • I am pretty sure this answer doesn't really work. I've tried a couple of times. – Tong Bruce Yang Apr 15 '14 at 19:29
  • You are pretty sure the answer does not work for you, and yet you ignore the fact that the code I have provided works for me? I am unable to assist unless you provide code of your own - this is necessary for me to be able to make a proper assessment and point out where you may be able to make changes to resolve your problem. – andrewbuilder Apr 16 '14 at 01:18
  • Please use the code in appcoda.com/search-bar-tutorial-ios7 and add the changes that you provide. – Tong Bruce Yang Apr 17 '14 at 04:48
  • This is the download link: https://dl.dropboxusercontent.com/u/2857188/RecipeAppSearchBar.zip – Tong Bruce Yang Apr 17 '14 at 04:50
  • OK, you are correct! I agree, you have found an unusual bug in Xcode. However I note this - after I added a `UISearchBar` to the `UITableViewController`, and before setting the delegate to the TVC and connecting to `UISearchDisplayController`, I did a Build & Run. The background was black! It is only after making the search bar an outlet of the search display controller, that the "top area" grey colour returns. – andrewbuilder Apr 17 '14 at 06:04
  • And I have also found a solution to your problem... see amended response to your question... – andrewbuilder Apr 17 '14 at 06:04
  • Nice! That's the solution. I think we can safely remove these 4 lines: [self.tableView setBackgroundView:nil]; [self.tableView setBackgroundColor:[UIColor blackColor]]; [self.searchDisplayController.searchResultsTableView setBackgroundView:nil]; [self.searchDisplayController.searchResultsTableView setBackgroundColor:[UIColor blackColor]]; – Tong Bruce Yang Apr 17 '14 at 17:21
  • I thought that too... and that was my answer for a few hours, but when I tried it in my own app, only the area above the table view was coloured. So I expect you will find those four lines are still required. – andrewbuilder Apr 17 '14 at 22:51
3

The problem arise when UISearchBar set as header view from Storyboard. Wrapping UISearchBar in UIView seems to solve the problem but brings other problems regarding compatibility with UISearchDisplayController.

I hacked into UI and basically found that UITableView positions a stub view between its top edge and header view and it's the first subview in UITableView hierarchy. Changing its background color won't work because it's updated on each scroll position change.

So my solution is to simply zero the alpha value for it. Therefore we delegate the background color to UITableView itself. It works perfectly fine on iOS 7.1 and seems to be a light-weight patch in this situation.

//
// Fix background color bug
// This patch can be applied once in viewDidLoad if you use UITableViewController
// http://stackoverflow.com/q/23026531/351305
//
- (void)_fixSearchBarHeaderViewBackgroundColorBug {
    // First subview in UITableView is a stub view positioned between table's top edge and table's header view.
    UIView* stubView = [self.tableView.subviews firstObject];

    // Make sure it's stub view and not anything else
    if([NSStringFromClass([stubView class]) isEqualToString:@"UIView"]) {
        // Set its alpha to zero to use background color from UITableView
        stubView.alpha = 0.0f;
    }
}
pronebird
  • 12,068
  • 5
  • 54
  • 82
1

I tried to use: self.tableView.backgroundView = [UIView new];. It worked!

Arnaud
  • 7,259
  • 10
  • 50
  • 71
chaoyao
  • 21
  • 2