如何使用 UISearchBar 或 UISearchDisplayController 作为 UICollectionView 标头?
Posted
技术标签:
【中文标题】如何使用 UISearchBar 或 UISearchDisplayController 作为 UICollectionView 标头?【英文标题】:How can I use UISearchBar or UISearchDisplayController as a UICollectionView header? 【发布时间】:2013-03-24 03:23:16 【问题描述】:我有一个 UICollectionView,其中有九个单元格。每个单元格都是一个正方形,因此它们以 3 x 3 的网格布局。这很好用,当设备旋转时,我调用performBatchUpdates:completion:
来强制collectionView 为新方向布置单元格。
这是没有搜索栏的样子:
我现在正尝试在 collectionView 顶部添加一个 UISearchBar,如下所示:
我尝试将它添加为标题视图,但它没有出现在顶部,而是占据了整个屏幕,并且单元格被推到了右侧。要查看它们,您可以滚动到没有搜索栏的地方。
要添加搜索栏,我尝试了两种方法。两者都不完全有效,而且似乎是一种糟糕的做法。我尝试的第一种方法是将搜索栏添加为标题视图。我的主视图是 UICollectionViewController 的子类。以下是我的设置方式:
- (void) viewDidLoad
// Set up some other things...
//
// Register the header view class
// which installs a search bar inside
// of itself.
//
[[self collectionView] registerClass:[PDReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"];
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
PDReusableView *header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath];
[header setFrame:[[[self navigationController] navigationBar] bounds]];
return header;
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
if (section == 0)
return CGSizeMake(collectionView.frame.size.width, self.navigationController.navigationBar.frame.size.height);
return CGSizeZero;
在 PDReusableView 内部,我安装了一个 UISearchBar。这是我得到的:
所以这种方法失败了,因为我无法将搜索控制器或搜索栏转换为可重用视图。如果我不能将它放入可重用的视图中,它就不能放入 UICollectionView。
我的另一个选择是调整集合视图的大小,这样它就不会占据整个屏幕。那么问题就变成了,我应该在视图层次结构中的哪里安装搜索栏?最简单的地方(虽然可能不正确)是应用程序委托,我在其中设置了视图层次结构的其余部分。通过将搜索栏安装在application:didFinishLaunchingWithOptions:
中,我设法让搜索栏出现在集合视图上方,这是我的代码:
UICollectionView *collectionView = [[self mainMenuViewController] collectionView];
CGRect f = [collectionView frame];
CGFloat height = [[[self navigationController] navigationBar] frame].size.height;
f.size.height -= height;
f.origin.y += height;
[collectionView setFrame:f];
// Cause the cells to be laid out per the new frame
[collectionView performBatchUpdates:nil completion:nil];
[[collectionView superview] addSubview:[self searchBar]];
[[self searchBar] setFrame:[[[self navigationController] navigationBar] bounds]];
虽然我可以继续向应用委托添加搜索逻辑,但这样做并不合适,因为我会在应用委托中维护数据集、过滤的搜索结果以及许多其他逻辑。我觉得 UICollectionViewController 子类是放置它的更合适的地方。
有没有办法在不使用 Interface Builder 的情况下在 UICollectionView 中安装 UISearchBar?怎么样?
编辑:
我正在使用普通的 UICollectionViewFlowLayout 并使用一些委托方法来设置单元格的大小等。
【问题讨论】:
我认为补充视图方法中缺少的是您的 UICollectionViewLayout 类的详细信息。您是否使用自定义子类?你的-layoutAttributesForItemAtIndexPath:
和-layoutAttributesForSupplementaryViewOfKind:atIndexPath:
方法是什么样的?
使用原版流布局。
如果你不希望你的 UISearchBar 用 UICollecitonView 滚动,在 CollectionView 之外实现它,搜索功能变得很容易控制
【参考方案1】:
我还没有使用过UICollectionView
或UICollectionViewController
,但我使用过UITableView
和UITableViewController
,我的一般经验法则是:如果你想做任何复杂的事情,就不要使用UITableViewController
。我怀疑UICollectionViewController
是类似的:一个相当脆弱、有限的视图控制器,实际上并不能为您节省很多麻烦。
因此,如果我处于您的位置,我只会考虑继承 UIViewController
并在我的视图控制器中包含 UICollectionView
。您的视图层次结构可能如下所示:
Root UIView
UISearchBar
UICollectionView
【讨论】:
看起来你可能是对的。我以前去过那里,完全可以理解。我会看看你的方法会产生什么效果。 @seamus Campbell thnx以上是关于如何使用 UISearchBar 或 UISearchDisplayController 作为 UICollectionView 标头?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 UISearchBar 或 UISearchDisplayController 作为 UICollectionView 标头?