xcode将文本string加载到UISearchController中
我正在使用这个例子通过UICollectionView进行search: 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]将返回一切,我得到一个错误,因为它不返回一个string…
' Can't use in/contains operator with collection <Place: 0x17d8ad70> (not a collection)'
但我想要它做的是通过p.PName结果search。 就像是:
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]
表示检查将不区分大小写。 -
%@
– 这是'某事'。 它将被replace为searchText
。
在这个例子中工作,因为数组包含NSString
对象和NSPredicate
知道如何检查它们是否contain
某些东西(一个子string)。 由于你的数组由Place
对象组成, NSPredicate
不知道如何检查它们是否contain
某些东西(一个子位置:P)。
为了解决这个问题,用这个self.PName contains[c] %@
replace谓词。 这将PName
每个数组对象的PName
属性,并检查它是否包含子string。
您可以阅读关于NSHipster上NSPredicate和文档的更多信息
至于第二个问题, self.dataSourceForSearchResult[indexpath.item]
实际上不会返回一个NSString
而是一个Place
对象,虽然不是所有东西,但是其中一个被过滤的。 它实际上从来没有在你的应用程序,因为它早些时候坠毁。 没有冒犯性,但是我认为你并没有完全理解这段代码的全部顺序。 打破它:
- 显示视图控制器和search栏是空的,所以根据
self.datasource
数据(或重命名它的self.entries
)绘制单元格。collectionView:cellForItemAtIndexPath:
被调用。 - 用户在search栏中input内容。 (这会触发
searchBar:textDidChange:
。 - 匹配的对象被过滤到
self.dataSourceForSearchResult
数组中。 - 集合视图被重新加载。
- 单元格重新绘制(
collectionView:cellForItemAtIndexPath:
被再次调用),但由于searchcollectionView: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; }