5

I don't want to show the "no results" text while my server is processing a search query.

enter image description here

I figured out the exact coordinates of the table cell that contains the label and attempted to cover it.

self.noResultsCoverView = [[[UIView alloc] initWithFrame:CGRectMake(
    0.0, 
    44.0, 
    320.0, 
    43.0
)] autorelease];
self.noResultsCoverView.backgroundColor = [UIColor whiteColor];
[self.searchDisplayController.searchResultsTableView addSubview:self.noResultsCoverView];

To my chagrin, my cover was above the table view, but below the label. I need the cover to be above the label. searchResultsTableView::bringSubviewToFront didn't work, which makes me believe that the label isn't a child of the searchResultsTableView at all.

BTW, this Stack Overflow answer doesn't quite work for me. It works on the very first search, but flashes a weird black cover on subsequent searches.

Community
  • 1
  • 1
JoJo
  • 19,587
  • 34
  • 106
  • 162

4 Answers4

20

this should do the work properly. The code to return at least one cell:

BOOL ivarNoResults; // put this somewhere in @interface or at top of @implementation
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        if (filteredList.count == 0) {
            ivarNoResults = YES;
            return 1;
        } else {
            ivarNoResults = NO;
            return [filteredList count];
        }
    }
    // {…}
    // return the unfiltered array count
}

and for "showing" the clean cell:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    if (tableView == self.searchDisplayController.searchResultsTableView && ivarNoResults) {
        static NSString *cleanCellIdent = @"cleanCell";
        UITableViewCell *ccell = [tableView dequeueReusableCellWithIdentifier:cleanCellIdent];
        if (ccell == nil) {
            ccell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cleanCellIdent] autorelease];
            ccell.userInteractionEnabled = NO;
        }
        return ccell;
    }

    // {…}
}
  • Instead of clean cell would be great to use some kind of huge-placeholder-cell with text like "Loading. Please wait!" Or something like that. – Anton Ogarkov Feb 05 '14 at 19:06
6

The easiest way to work around this is to return 1 in numberOfRowsInSection while the query is in progress and leave the dummy cell empty or set its hidden property to YES so it is not visible.

Felix
  • 35,354
  • 13
  • 96
  • 143
  • This lead me to the correct solution. Other things I needed to take care of was (1) `heightForRowAtIndexPath` needed to return a tall enough height to cover the whole screen such as `self.view.frame.size.height` and (2) `cellForRowAtIndexPath` needed to return a blank table cell. These two things will blank out the entire table during searching. – JoJo Aug 03 '12 at 23:12
3

Try this it worked for me

In the UISearchDisplayController delegate do this:=

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.001);
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        for (UIView* v in self.searchDisplayController.searchResultsTableView.subviews) {
            if ([v isKindOfClass: [UILabel class]] && 
                [[(UILabel*)v text] isEqualToString:@"No Results"]) {
                [(UILabel*)v setText:@""];
                break;
            }
        }
    });
    return YES;
}
Piyush Kashyap
  • 1,965
  • 1
  • 14
  • 16
  • 3
    I would not suggest doing this. This can break in the future. – lostInTransit Jul 30 '12 at 11:17
  • @lostInTransit can you explain me how it could break in future ?? – Piyush Kashyap Jul 30 '12 at 11:26
  • The label is added by Apple. And you are checking the label's text. Say in a future version of the iOS SDK, they change the label text, the developer will have to submit a revision, just for that 1 change. – lostInTransit Jul 30 '12 at 13:22
  • I think that change is not very big,Can you suggest me a better way of solving this problem ?? – Piyush Kashyap Jul 30 '12 at 13:27
  • I did not say it was wrong, just that I would not suggest doing this coz this might break in the future. – lostInTransit Jul 30 '12 at 14:13
  • But I don't think Apple is going to change "No Results" text in near future and if apple changes the text then it won't be a big task for the developer to change the text again :) – Piyush Kashyap Jul 30 '12 at 14:20
  • 1
    @sparrowhawk don't argue with that. It's **always** a bad idea to dig in Apple's UI and try to hide things no matter how you turn it. Your solution will not even work today because this text is localized. People in non-english speaking countries will see curious things happen. Just stop defending a bad behavior and start listen to people. (and it is a big task for the developer just think how long it takes to get reviewed for the AppStore) –  Aug 02 '12 at 08:50
  • @phix23 Yes the solution is for english language only – Piyush Kashyap Aug 02 '12 at 11:31
1

You need to realize that when you have a UISearchDisplayController, and the search bar is active, the UITableView argument passed into your UITableView data source and delegate methods is in fact NOT your tableView object, but a tableView managed by the UISearchDisplayController, intended to display "live" search results (perhaps results filtered from your main data source, for example).

You can easily detect this in code, and then return the appropriate result from the delegate/data source method, depending on which tableView object is asking.

For example:

- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section
{
    if (tv == self.searchDisplayController.searchResultsTableView) {
        // return the number of rows in section for the visible search results.
        // return a non-zero value to suppress "No results"
    } else {
        // return the number of rows in section for your main data source
    }
}

The point is that your data source and delegate methods are serving two tables, and you can (and should) check for which table is asking for data or delegation.

By the way, the "No results" is (I believe) provided by a background image which the UISearchDisplayController displays when the delegate says there are no rows... You are not seeing a 2-row table, the first blank and the second with text "No results". At least, that's what I think is happening there.

Mark Granoff
  • 16,878
  • 2
  • 59
  • 61
  • The "No Results" is part of the tableview, not at the background level. It scrolls with the cell it is added to. It is mostly centered, as it shows on the 3rd cell down for 4" screens. Setting the background view to nil and color to something else, does not help. The only way I've found to suppress it is to add your own empty cell before showing results. – Bill Burgess Jan 08 '14 at 01:33