我用这个例子通过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;
}
...只有我的应用程序是安装程序有点不同:
- (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;
}
所以,如果我只是运行它,它是这样的,然后self.dataSourceForSearchResult [indexpath.item]将返回的一切,我得到一个错误,因为它没有返回一个字符串...
“ Can't use in/contains operator with collection <Place: 0x17d8ad70> (not a collection)'
但我想它做的是通过p.PName结果搜索。 就像是:
self.dataSourceForSearchResult[p.PName indexpath.item]
通过GitHub的代码说完看着我认为你的问题的核心在于别的地方。
问题就出在这里:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"self contains[c] %@", searchText];
self.dataSourceForSearchResult = [self.dataSource filteredArrayUsingPredicate:resultPredicate];
}
什么这种方法确实是它过滤匹配从项目self.datasource
(我假设你改名为self.entries
,我希望你也这样做是在这里)基于谓词。 谓词是有点棘手理解,特别是如果你跟他们没有经验。 让我们来分析一下:
self
-在这种情况下就意味着会针对情况进行检查的对象。 该目的将是数组的一个元素。
contains[c]
-这是条件。 该self
是否会进行检查contains
的东西。 在[c]
表示该项检查将是不区分大小写的。
%@
-这是“东西”。 它将被替换searchText
。
这个工作的例子,因为该数组包含NSString
对象和NSPredicate
知道如何检查它们是否contain
东西(一个字符串)。 由于您的阵列由Place
对象的NSPredicate
不知道如何检查是否contain
东西(一个subplace:P)。
为了解决这个问题替换这一个谓词self.PName contains[c] %@
。 这一个将存取权限的PName
阵列的每个对象的属性,并检查它是否包含的子字符串。
你可以阅读更多的NSPredicate上NSHipster并在文档
至于第二个问题, self.dataSourceForSearchResult[indexpath.item]
不会实际上返回NSString
但一个Place
对象,虽然不是EVERYTHING
,但过滤的一个。 它实际上从来没有在您的应用程序达到了,因为它早崩溃了。 没有进攻,但我认为你不完全理解的东西在这个代码的整个秩序。 要打破它:
- 视图控制器被示出和搜索栏是空的,所以将细胞绘制,基于在数据
self.datasource
(或self.entries
你重新命名)。 collectionView:cellForItemAtIndexPath:
被调用。 - 用户输入的搜索栏的东西。 (这将触发
searchBar:textDidChange:
- 匹配对象是过滤到
self.dataSourceForSearchResult
阵列。 - 集合视图获取重新加载。
- 这些细胞重新绘制(
collectionView:cellForItemAtIndexPath:
被再次调用),但由于搜索栏是不是空的,我们现在从对象只使用self.dataSourceForSearchResult
。
因此,为了使工作您- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath;
应该是这样的:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
PlaceCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
Place *p;
// retrieve item from appropriate array
if (self.searchBarActive) {
p = self.dataSourceForSearchResult[indexPath.item];
} else {
p = self.entries[indexPath.item];
}
// populate the cell - we do this regardless of whether the searchbar is active or not
cell.placeName.text = p.PName;
cell.placeImg.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:p.PImage]]];
return cell;
}