I was using this example for searching through a UICollectionView: https://github.com/ihomam/CollectionViewWithSearchBar/blob/master/collevtionViewWithSearchBar/CollectionViewController.m
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
CollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// Configure the cell
if (self.searchBarActive) {
cell.laName.text = self.dataSourceForSearchResult[indexPath.row];
} else {
cell.laName.text = self.dataSource[indexPath.row];
}
return cell;
}
...only my app is setup a little differently:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
PlaceCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
Place *p = [_entries objectAtIndex:indexPath.item];
if (self.searchBarActive) {
cell.placeName.text = self.dataSourceForSearchResult[indexPath.item];
} else {
cell.placeName.text = p.PName;
cell.placeImg.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:p.PImage]]];
}
return cell;
}
So if I just run it the way it is then self.dataSourceForSearchResult[indexpath.item] will return EVERYTHING and I get an error because it's not returning a string...
'Can't use in/contains operator with collection <Place: 0x17d8ad70> (not a collection)'
but what I want it to do is search through the p.PName results. Something like:
self.dataSourceForSearchResult[p.PName indexpath.item]
Having looked through the github code I think that the core of your problem lies somewhere else.
The problem lies here :
What this method does is it filters matching items from
self.datasource
(which I assume you renamed toself.entries
, and I hope you also did it here) based on the predicate. The predicate is a little tricky to understand, especially if you have no previous experience with them. Let's break it down :self
- in this context it means the object that will be checked against the condition. This object will be an element of the array.contains[c]
- this is the condition. Theself
will be checked if itcontains
something. The[c]
means that the check will be case insensitive.%@
- this is the 'something'. It will be replaced withsearchText
.This worked in the example because the array contained
NSString
objects andNSPredicate
knows how to check if theycontain
something (a substring). Since your array consists ofPlace
objects theNSPredicate
doesn't know how to check if theycontain
something (a subplace? :P).To fix this replace the predicate with this one
self.PName contains[c] %@
. This one will acces thePName
property of each object of array and check whether it contains the substring.You can read more on NSPredicate on NSHipster and in the docs
As to the second problem,
self.dataSourceForSearchResult[indexpath.item]
will not in fact return anNSString
but aPlace
object, though notEVERYTHING
, but one of the filtered ones. It was actually never reached in your app, as it crashed earlier. No offence, but I think that you don't entirely understand the whole order of things in this code. To break it down :self.datasource
(orself.entries
as you renamed it).collectionView:cellForItemAtIndexPath:
is being called.searchBar:textDidChange:
).self.dataSourceForSearchResult
array.collectionView:cellForItemAtIndexPath:
is being called again), but since the searchbar is not empty, we now use only objects fromself.dataSourceForSearchResult
.So to make it work your
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
should look like this :