// // KBSearchResultVC.m // keyBoard // // 搜索结果页:顶部为 KBSearchBarView,下面为两列卡片的 UICollectionView。 // - Masonry 约束 // - 懒加载子视图 // - 中文注释 // #import "KBSearchResultVC.h" #import "KBSearchBarView.h" #import "KBSkinCardCell.h" static NSString * const kResultCellId = @"KBSkinCardCell"; @interface KBSearchResultVC () // 顶部搜索栏(复用已封装的 KBSearchBarView) @property (nonatomic, strong) KBSearchBarView *searchBarView; // 结果列表 @property (nonatomic, strong) UICollectionView *collectionView; @property (nonatomic, strong) UICollectionViewFlowLayout *flowLayout; // 数据源(示例数据,实际项目中由网络返回) @property (nonatomic, strong) NSMutableArray *resultItems; // @{title, price} @end @implementation KBSearchResultVC - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; // 添加子视图 [self.view addSubview:self.searchBarView]; [self.view addSubview:self.collectionView]; // Masonry 布局:搜索在顶部,列表紧随其下 [self.searchBarView mas_makeConstraints:^(MASConstraintMaker *make) { // 顶部与导航栏底对齐,左右各 16 间距,高度 40 make.top.equalTo(self.view.mas_top).offset(KB_NAV_TOTAL_HEIGHT + 8); make.left.equalTo(self.view).offset(16); make.right.equalTo(self.view).offset(-16); make.height.mas_equalTo(40); }]; [self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.searchBarView.mas_bottom).offset(12); make.left.right.bottom.equalTo(self.view); }]; // 默认关键字(如果有) if (self.defaultKeyword.length > 0) { [self.searchBarView updateKeyword:self.defaultKeyword]; [self performSearch:self.defaultKeyword]; } else { // 填充一些示例数据 [self loadMockData]; } } #pragma mark - Private /// 执行搜索(示例:本地生成一些数据) - (void)performSearch:(NSString *)keyword { // 这里可以发起网络请求;演示中生成 10 条假数据 [self.resultItems removeAllObjects]; for (int i = 0; i < 10; i++) { [self.resultItems addObject:@{ @"title": @"Dopamine", @"price": @"20" }]; } [self.collectionView reloadData]; } /// 示例数据 - (void)loadMockData { [self.resultItems removeAllObjects]; for (int i = 0; i < 12; i++) { [self.resultItems addObject:@{ @"title": @"Dopamine", @"price": @"20" }]; } [self.collectionView reloadData]; } #pragma mark - UICollectionViewDataSource - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView { return 1; } - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return self.resultItems.count; } - (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { KBSkinCardCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kResultCellId forIndexPath:indexPath]; NSDictionary *it = self.resultItems[indexPath.item]; [cell configWithTitle:it[@"title"] imageURL:nil price:it[@"price"]]; return cell; } #pragma mark - UICollectionViewDelegateFlowLayout - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { // 两列布局 CGFloat width = collectionView.bounds.size.width; CGFloat inset = 16; // 左右间距 CGFloat spacing = 12; // 列间距 CGFloat w = floor((width - inset * 2 - spacing) / 2.0); CGFloat h = w * 0.75 + 8 + 20 + 10 + 6 + 8; // 与 KBSkinCardCell 估算一致 return CGSizeMake(w, h); } - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { return UIEdgeInsetsMake(8, 16, 20, 16); } - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section { return 12; } - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section { return 16; } #pragma mark - Lazy - (KBSearchBarView *)searchBarView { if (!_searchBarView) { _searchBarView = [[KBSearchBarView alloc] init]; _searchBarView.placeholder = @"Themes"; __weak typeof(self) weakSelf = self; _searchBarView.onSearch = ^(NSString * _Nonnull keyword) { [weakSelf performSearch:keyword]; }; } return _searchBarView; } - (UICollectionViewFlowLayout *)flowLayout { if (!_flowLayout) { _flowLayout = [[UICollectionViewFlowLayout alloc] init]; _flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical; } return _flowLayout; } - (UICollectionView *)collectionView { if (!_collectionView) { _collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:self.flowLayout]; _collectionView.backgroundColor = [UIColor whiteColor]; _collectionView.dataSource = self; _collectionView.delegate = self; // 注册结果卡片 cell [_collectionView registerClass:KBSkinCardCell.class forCellWithReuseIdentifier:kResultCellId]; } return _collectionView; } - (NSMutableArray *)resultItems { if (!_resultItems) { _resultItems = [NSMutableArray array]; } return _resultItems; } @end