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
,而是一个过滤后的。它实际上从未在您的应用程序中到达,因为它早些时候崩溃了。没有冒犯,但我认为您并不完全理解这段代码中的全部顺序。分解它:
- 显示视图控制器并且搜索栏为空,因此根据
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;
}
我使用此示例搜索 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
,而是一个过滤后的。它实际上从未在您的应用程序中到达,因为它早些时候崩溃了。没有冒犯,但我认为您并不完全理解这段代码中的全部顺序。分解它:
- 显示视图控制器并且搜索栏为空,因此根据
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;
}