16
votes

If you use a UISearchDisplayController with a UITableViewController, when the user taps the search bar it animates up to replace the nav bar.

I'd like to get that same effect when using a UISearchBar at the top of a UICollectionViewController. Any ideas?

3
Hey, have you made any progress on this question ? I'm trying to do the same... All I've done till now is add a searchbar as section header, but it doesn't really render fine.aspyct
Anyone?? I could use this as well... seems like the best solution at this point may be to just subclass the UISearchBar/UISearchDisplayController and teach them how to interact with the UICollectionView.Raconteur
I've been working on something at work trying to replicate uisearchdisplaycontroller and it isn't easy.Sam Corder

3 Answers

2
votes

I had to add the searchBar programmatically as a subview of the UICollectionReusableView, I could never getting it working through IB as I kept getting prototype error when assigning an outlet. Adding the search bar in the implementation file worked for me.

The relevant methods are the following.

-(void)viewDidLoad
{
    [super viewDidLoad];
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:CellIdentifier];
    _objectChanges = [NSMutableArray array];
    _sectionChanges = [NSMutableArray array];
    [self performFetch];
    searchBar = [[UISearchBar alloc]
                  initWithFrame:CGRectMake(0.0, 50.0, self.view.bounds.size.width,
                                           44.0)];
    searchBar.placeholder = @"Search for channels";
    searchBar.tintColor = [UIColor blackColor];
    searchBar.delegate = self;
}


-(UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
    SupplementaryView *header = nil;

    if ([kind isEqual:UICollectionElementKindSectionHeader])
    {
        header = [self.collectionView dequeueReusableSupplementaryViewOfKind:kind
                                                    withReuseIdentifier:@"reuseHeader"
                                                           forIndexPath:indexPath];

        [header addSubview:searchBar];

    }
    return header;
}
1
votes

I just had the same inquiry, and I came up with a half-baked but working solution that does not involve rewriting UISearchDisplayController.

(END RESULT: A UITableView --that answers to shouldReloadTableForSearchString-- overlaid on top of the UICollectionView, once you click search it's dismissed, and you have your results in the collectionView. Read on if this is of interest)

In the IB created a UIViewController in which I inserted(see screenshot): a view for layout purposes --> in which I first dropped a UISearchBar and display controller. In the same view (side by side) I dropped a UICollectionView with a custom UICollectionViewCell. Then I dropped in a UITableViewProvider (with a custom UITableCell, but that's not required, you can also ignore the UITabBarItem and the Nav item in the screenshot, that's inconsequential )

I set the height of the UITableView to 0, and wired all the Outlets and delegates, and the net result is the following, when the cursor enters the UISearchBox, the UITableView overlay on top the UICollectionView, as one types the shouldReloadTableForSearchString del gets called and the results appear in the tableView; On searchBarSearchButtonClicked I simply set the dataSource of the UICollectionView and call reloadData on it's outlet, et Voila.

One would think Apple should generecize the search display controller; maybe in a future release?

( This works because that's the way the UISearchDisplay controller is optimized, IIRC there's actually one UITableView per character entry stacked on top of each other )

(Not posting code because there's quite a bit involved; plz inquire if anything is not straightforward)

enter image description here

0
votes

Here just a swift code - worked for me!

func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {

    let headerView = self.mainPictureCollectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "headerView", forIndexPath: indexPath)

    headerView.addSubview(searchBar)
    return headerView
}