Question

I have a list of things provided by the system (e.g. brands) which are not user editable but have to change from time to time.

Context

These things are displayed in a table view and are searchable using the default UISearchDisplayController. However, as the list of things surely isn't complete I want to give users the ability to request the addition of other things to the list. To do so I added a table footer view to both the original table view and the search results table view, which provides a button to send a mail.

Problem

It works fine as long as the search results table view still contains entries. My table footer view is displayed below the search results and everything is fine.

However, if no results are found for a search term, the search display controller displays a "no result" label centered over the table view. This usually looks great, like this:

default

But since my tableFooterView is still displayed (which I want it to be!) the "no results" label overlaps my footer view and it looks crappy:

enter image description here

I think in my case I don't need the "no result"s label, since my footer view makes it reasonable clear that there are no results and what to do about it. I don't mind it either, as long as it doesn't overlap.

Question

How can I either

  • make the search view not display the "No Results" label
  • or configure how it is displayed (-> not overlapping)

If this is not possible I'm also open to suggestions for others ways of displaying the footer view (not as footer), which would not have this problem. But I like the solution since I can use it in both cases (normal table view and search results table view) without having to change anything.

Was it helpful?

Solution

First of all, it is important to keep in mind that using UISearchDisplayController is a trade-off between customizability and convenience. You get a lot of automatic stuff for free, but if you require a lot of customization it might not suit your needs. It works best as a drop-in solution, and if you'd really like to use it, I recommend you work your app around it instead of trying to hack its behavior.

With that said, why don't you make the UITableView return a single row when there are no results? This row could either be empty, display some boilerplate text or an image (sad face or something humorous that matches the app).

Having a single row to be presented, the default "No Results" label from UISearchDisplayController would not be shown. This is the default behavior for a lot of Apps, like Instagram (check out the Explore tab), Kindle and the default Notes.app, although they are probably not using UISearchDisplayController.

If you find that this workaround doesn't fit your app, you could also try making the "Missing a Brand" view into the header view of the first section of the UISearchResultsTableView (instead of the footer view). That way, the "No Results" label would be displayed below it. Combining this idea with a single empty row would even work better.

A third option would be to insert this view on top of the UISearchResultsTableView. This could be done every time there were no results (properly removing it when necessary) or just a single time, using its hidden property to show or hide it instead.

Any other method for hiding this label is probably hacky, like this one: https://stackoverflow.com/a/11715841/382834. Although easier on your current logic, it might have negative consequences later on, so it's possibly the worst path to follow.

OTHER TIPS

Use UISearchBar It will not hide Navigationbar

Import UISearchBar Delegate <UISearchBarDelegate>

Don't forget to connect delegate with your searchbar

[yourSearchbar setDelegate:self]

Then Add these delegate methods,

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
   // Put here in search what you want.
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)aSearchBar
{
    [aSearchBar resignFirstResponder];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
    [searchBar setShowsCancelButton:YES animated:YES];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
    [searchBar resignFirstResponder];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
    [searchBar resignFirstResponder];
}

What I did is to detect if there are 0 results. If there are 0 results I changed numberOfRowsInSection to return 1, heightForRowAtIndexPath to return 0 and cellForRowAtIndexPath to return a generic UITableViewCell.

That's it. Footer is shown in all it's glory.

I'd love to show you my solution.

First I wrote some categories. The first category gives us UISearchDisplayController table.

@interface UITableViewController (YourUITableViewControllerCategory)
- (UITableView *) tableViewSearch;
@end

@implementation UITableViewController (YourUITableViewControllerCategory)
- (UITableView *) tableViewSearch
{
    if ([self respondsToSelector:@selector(searchDisplayController)])
    {
        id searchDisplayController = [self performSelector:@selector(searchDisplayController)];
        if ([searchDisplayController respondsToSelector:@selector(searchResultsTableView)])
        {
            id searchResultsTableView = [searchDisplayController performSelector:@selector(searchResultsTableView)];
            if ([searchResultsTableView isKindOfClass:[UITableView class]]) return searchResultsTableView;
        }
    }
    return [UITableView new];
}
@end

The second category returns an array of subview of certain type.

@interface UIView (YourUIViewCategory)
- (NSArray *) viewsWithClass:(NSString *)class;
@end

@implementation UIView (YourUIViewCategory)
- (NSArray *) viewsWithClass:(NSString *)class
{
    NSMutableArray *array = [NSMutableArray new];
    for (UIView *view in self.subviews)
    {
        if ([view isMemberOfClass:NSClassFromString(class)])
        {
            [array addObject:view];
        }
        [array addObjectsFromArray:[view viewsWithClass:class]];
    }
    return array;
}
@end

Now you are almost ready to search for "No results" label. You have to be sure that all labels in your cells have tag != 0.

- (BOOL) searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
    for (UILabel *label in [self.tableViewSearch viewsWithClass:NSStringFromClass([UILabel class])])
    {
        if (label.tag == 0)
        {
            // found it! do whatever you want with label
        }
    }
    return NO;
}

Its just my approach. You can find your own way. Good luck!

use the below code to remove the "no result" text value

- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView {
if (!isChangedNoResults) {
    if ([contactManager.filteredPeople count] == 0) {
        [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(changeNoResultsText:) userInfo:nil repeats:YES];
    }
}}

change the text method.

- (void) changeNoResultsText:(NSTimer *)timer {
if (isChangedNoResults) {
    [timer invalidate];
}
else {
    for (UIView *subview in [self.searchDisplayController.searchResultsTableView subviews]) {
        if ([subview isKindOfClass:[UILabel class]]) {
            UILabel *targetLabel = (UILabel *)subview;
            if ([targetLabel.text isEqualToString:@"No Results"]) {
                NSLog(@"Changed!");
                [targetLabel setText:@"_____"];
                isChangedNoResults = YES;
                [timer invalidate];
            }
        }
    }
}

}

or do the below code in search method

-(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;
        }
    }
});

its really helpful to me,,, try it

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top