11

I'm trying to create a UISearchDisplayController programmatically. I have a method which should set up my search controller, but when I call it, nothing happens.

This my -setupSearch method:

- (void)setupSearch {
    UISearchBar *myBar;
    UISearchDisplayController *myCon;

    myBar = [[UISearchBar alloc] initWithFrame:CGRectZero];
    [myBar sizeToFit];

    myCon = [[UISearchDisplayController alloc]
             initWithSearchBar:myBar contentsController:self];
    [myBar release];

    myCon.delegate = self;
    myCon.searchResultsDataSource = self;
    myCon.searchResultsDelegate = self;

    /* Setup scopes */
    {
        NSMutableArray *scopes;
        NSUInteger count, i;
        NSString *aScope;

        count = SCOPE_COUNT;
        scopes = [[NSMutableArray alloc] initWithCapacity:count];
        for(i = 0; i < count; i++) {
            // I create four scopes here
        }

        myCon.searchBar.scopeButtonTitles = scopes;
        [scopes release];
    }

    [myCon release];
}

I call the above method in the -viewDidLoad method of my subclassed UITableViewController. Unfortunately nothing happens when my table view controller get's displayed in a UITabBarController.

Any help would be greatly appreciated.

v1Axvw
  • 3,054
  • 3
  • 26
  • 40

1 Answers1

13

Check out the example code in: [https://github.com/JayMarshal/GrabCasts.com-iPhone-Client/blob/master/CoreDataTableViewController.m][1]

Repo here: https://github.com/JayMarshal/Grabcasts

It is an expanded version of the coredatatableviewcontroller of the stanford iOS courses.

Relevant snippet of that code follows:

- (void)createSearchBar {
if (self.searchKey.length) {
    if (self.tableView && !self.tableView.tableHeaderView) {
        UISearchBar *searchBar = [[[UISearchBar alloc] init] autorelease];
        self.searchDisplayController 
               = [[UISearchDisplayController alloc] initWithSearchBar:searchBar
                                                   contentsController:self];
        self.searchDisplayController.searchResultsDelegate = self;
        self.searchDisplayController.searchResultsDataSource = self;
        self.searchDisplayController.delegate = self;
        searchBar.frame = CGRectMake(0, 0, 0, 38);
        self.tableView.tableHeaderView = searchBar;
    }
} else {
    self.tableView.tableHeaderView = nil;
}

Basically it attaches the UISearchDisplayController to self (which must be a tableviewcontroller) as a side effect of the initialization. So setting:

self.searchDisplayController.searchResultsDelegate = self;
self.searchDisplayController.searchResultsDataSource = self;

Instead of

myCon.searchResultsDataSource = self;
myCon.searchResultsDelegate = self;

Might do the trick. In debugging, check whether myCon and self.searchDisplayController are pointing to the same object?

Updated: there seems to be a bug in the SDC property of the TVC that it is not retained in the runloop. Filed as: http://openradar.appspot.com/10254897 also mentioned on SO, see UIViewController does not retain its programmatically-created UISearchDisplayController

Community
  • 1
  • 1
Bjinse
  • 1,339
  • 12
  • 25
  • 2
    From the doc, on contentsController: "This is typically an instance of UITableViewController.". Typically, not required. – Jacob Jennings May 03 '13 at 21:56
  • So if you do not want to use a `UITableViewController`, you can simply have a `UIViewController` that conforms to the protocols `UITableViewDataSource` and `UITableViewDelegate`. – Matthew Quiros Oct 03 '13 at 16:02
  • 7
    My problem with this is that `self.searchDisplayController` is a readonly property on `UITableViewController`, and yet the code here is setting it. – Tyler Cloutier Apr 03 '14 at 00:36
  • The property is redeclared as read/write in CoreDataTableViewController.h The repo mentioned does not seem to include this source file anymore though. – Bjinse Apr 04 '14 at 09:37
  • 4
    when you init the searchDisplayController (and set it to a strong property, to retain it) it will automatically set the searchDisplayController of the UIViewController you pass to it's initWithSearchBar... method – GreatWiz May 26 '14 at 19:25