Files
keyboard/keyBoard/Class/Search/VC/KBSearchResultVC.m
2025-11-08 20:04:50 +08:00

170 lines
5.7 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// KBSearchResultVC.m
// keyBoard
//
// 搜索结果页:顶部为 KBSearchBarView下面为两列卡片的 UICollectionView。
// - Masonry 约束
// - 懒加载子视图
// - 中文注释
//
#import "KBSearchResultVC.h"
#import "KBSearchBarView.h"
#import "KBSkinCardCell.h"
static NSString * const kResultCellId = @"KBSkinCardCell";
@interface KBSearchResultVC ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
// 顶部搜索栏(复用已封装的 KBSearchBarView
@property (nonatomic, strong) KBSearchBarView *searchBarView;
// 结果列表
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) UICollectionViewFlowLayout *flowLayout;
// 数据源(示例数据,实际项目中由网络返回)
@property (nonatomic, strong) NSMutableArray<NSDictionary *> *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<NSDictionary *> *)resultItems {
if (!_resultItems) {
_resultItems = [NSMutableArray array];
}
return _resultItems;
}
@end