xcode 将文本字符串加载到 UISearchController

xcode Loading a text string into a UISearchController

我使用此示例搜索 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] 将 return 一切,我得到一个错误,因为它不是 return输入字符串...

'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] 表示检查将不区分大小写。

  • %@ - 这就是 'something'。它将替换为 searchText.

这在示例中有效,因为数组包含 NSString 个对象并且 NSPredicate 知道如何检查它们是否 contain 某些东西(子字符串)。由于您的数组由 Place 个对象组成,因此 NSPredicate 不知道如何检查它们是否 contain 某些东西(一个子位置?:P)。

要解决这个问题,请用这个 self.PName contains[c] %@ 替换谓词。这将访问数组的每个对象的 PName 属性 并检查它是否包含子字符串。

您可以在 NSHipster and in the docs

上阅读有关 NSPredicate 的更多信息

至于第二个问题,self.dataSourceForSearchResult[indexpath.item]实际上不会return一个NSString而是一个Place对象,虽然不是EVERYTHING,而是一个过滤后的。它实际上从未在您的应用程序中到达,因为它早些时候崩溃了。没有冒犯,但我认为您并不完全理解这段代码中的全部顺序。分解它:

  1. 显示视图控制器并且搜索栏为空,因此根据 self.datasource(或您重命名的 self.entries 中的数据绘制单元格)。 collectionView:cellForItemAtIndexPath: 正在通话中。
  2. 用户在搜索栏中输入内容。 (这会触发 searchBar:textDidChange:)。
  3. 匹配的对象被过滤到self.dataSourceForSearchResult数组中。
  4. 集合视图重新加载。
  5. 重新绘制单元格(再次调用 collectionView:cellForItemAtIndexPath:),但由于搜索栏不为空,我们现在仅使用来自 self.dataSourceForSearchResult.
  6. 的对象

因此,要使其正常工作,您的 - (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;
}