Ios xcode将文本字符串加载到UISearchController中

Ios xcode将文本字符串加载到UISearchController中,ios,xcode6,uicollectionview,uisearchcontroller,Ios,Xcode6,Uicollectionview,Uisearchcontroller,我使用此示例在UICollectionView中搜索: …只有我的应用程序设置有点不同: - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { PlaceCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:re

我使用此示例在UICollectionView中搜索:

…只有我的应用程序设置有点不同:

- (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]的方式运行它,那么它将返回所有内容,并且我得到一个错误,因为它没有返回字符串

不能将in/contains运算符与集合(非集合)一起使用”

但我想让它做的是搜索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
    -在此上下文中,它表示将根据条件检查的对象。此对象将是数组的一个元素

  • 包含[c]
    -这是条件。如果
    自身包含
    内容,则将检查
    自身。
    [c]
    表示检查不区分大小写

  • %@
    -这是“某物”。它将替换为
    searchText

这在示例中起作用,因为数组包含
NSString
对象,并且
NSPredicate
知道如何检查它们是否包含
某些内容(子字符串)。由于数组由
Place
对象组成,
NSPredicate
不知道如何检查它们
是否包含
内容(子位置?:P)

要修复此问题,请将谓词替换为该谓词。
self.PName包含[c]@
。这个函数将访问数组中每个对象的
PName
属性,并检查它是否包含子字符串

您可以在上和中阅读有关NSPredicate的更多信息


至于第二个问题,
self.dataSourceForSearchResult[indexpath.item]
实际上不会返回
NSString
,而是
Place
对象,虽然不是
所有内容,而是其中一个经过过滤的对象。它实际上从未在你的应用程序中访问过,因为它早些时候崩溃了。无意冒犯,但我认为您并不完全理解此代码中的所有顺序。要分解它:

  • 视图控制器显示,搜索栏为空,因此根据
    self.datasource
    中的数据(或您重命名的
    self.entries
    中的数据)绘制单元格<代码>集合视图:正在调用cellForItemAtIndexPath:
  • 用户在搜索栏中输入一些内容。(这将触发搜索栏: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;
    }
    

    您是否尝试过:shouldChangeTextInRange:(NSRange)range replacementText:(NSString*_Nonnull)text不确定您的意思。。。你能详细说明或给我一个例子的链接吗?哇。。。只是哇!这真是太棒了。谢谢。我听了你的建议,现在它很好用。现在让我困惑的一件事是:当我输入时,它会过滤匹配的对象并重新加载集合。。。但如果我退格,它就不会回到原始视图。如果我按了取消按钮。这是我第一次运行程序的时候。。。但现在不行。奇怪。。。它应该是重新加载,因为我删除,它应该肯定刷新时,我点击取消按钮。(仅当我键入新文本时才会更改)。你知道发生这种情况的原因吗?让我们继续聊下去,不要把原来的问题弄得一团糟:
    - (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;
    }