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对象,虽然不是所有东西,但是其中一个被过滤的。 它实际上从来没有在你的应用程序,因为它早些时候坠毁。 没有冒犯性,但是我认为你并没有完全理解这段代码的全部顺序。 打破它:

  1. 显示视图控制器和search栏是空的,所以根据self.datasource数据(或重命名它的self.entries )绘制单元格。 collectionView:cellForItemAtIndexPath:被调用。
  2. 用户在search栏中input内容。 (这会触发searchBar:textDidChange:
  3. 匹配的对象被过滤到self.dataSourceForSearchResult数组中。
  4. 集合视图被重新加载。
  5. 单元格重新绘制( 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; }