3
This commit is contained in:
@@ -2,11 +2,6 @@
|
|||||||
// KBSearchResultVC.m
|
// KBSearchResultVC.m
|
||||||
// keyBoard
|
// keyBoard
|
||||||
//
|
//
|
||||||
// 搜索结果页:顶部为 KBSearchBarView,下面为两列卡片的 UICollectionView。
|
|
||||||
// - Masonry 约束
|
|
||||||
// - 懒加载子视图
|
|
||||||
// - 中文注释
|
|
||||||
//
|
|
||||||
|
|
||||||
#import "KBSearchResultVC.h"
|
#import "KBSearchResultVC.h"
|
||||||
#import "KBSearchBarView.h"
|
#import "KBSearchBarView.h"
|
||||||
@@ -16,7 +11,9 @@ static NSString * const kResultCellId = @"KBSkinCardCell";
|
|||||||
|
|
||||||
@interface KBSearchResultVC ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
@interface KBSearchResultVC ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
||||||
|
|
||||||
// 顶部搜索栏(复用已封装的 KBSearchBarView)
|
// 顶部自定义栏:返回按钮 + 搜索栏
|
||||||
|
@property (nonatomic, strong) UIView *topBar;
|
||||||
|
@property (nonatomic, strong) UIButton *backButton;
|
||||||
@property (nonatomic, strong) KBSearchBarView *searchBarView;
|
@property (nonatomic, strong) KBSearchBarView *searchBarView;
|
||||||
|
|
||||||
// 结果列表
|
// 结果列表
|
||||||
@@ -35,20 +32,32 @@ static NSString * const kResultCellId = @"KBSkinCardCell";
|
|||||||
self.view.backgroundColor = [UIColor whiteColor];
|
self.view.backgroundColor = [UIColor whiteColor];
|
||||||
|
|
||||||
// 添加子视图
|
// 添加子视图
|
||||||
[self.view addSubview:self.searchBarView];
|
[self.view addSubview:self.topBar];
|
||||||
|
[self.topBar addSubview:self.backButton];
|
||||||
|
[self.topBar addSubview:self.searchBarView];
|
||||||
[self.view addSubview:self.collectionView];
|
[self.view addSubview:self.collectionView];
|
||||||
|
|
||||||
// Masonry 布局:搜索在顶部,列表紧随其下
|
// Masonry 布局:顶部自定义栏(无导航栏)
|
||||||
[self.searchBarView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.topBar mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
// 顶部与导航栏底对齐,左右各 16 间距,高度 40
|
make.top.equalTo(self.view.mas_top).offset(KB_STATUSBAR_HEIGHT + 8);
|
||||||
make.top.equalTo(self.view.mas_top).offset(KB_NAV_TOTAL_HEIGHT + 8);
|
make.left.right.equalTo(self.view);
|
||||||
make.left.equalTo(self.view).offset(16);
|
make.height.mas_equalTo(44);
|
||||||
make.right.equalTo(self.view).offset(-16);
|
}];
|
||||||
make.height.mas_equalTo(40);
|
[self.backButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.topBar).offset(12);
|
||||||
|
make.centerY.equalTo(self.topBar);
|
||||||
|
make.width.mas_equalTo(28);
|
||||||
|
make.height.mas_equalTo(36);
|
||||||
|
}];
|
||||||
|
[self.searchBarView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.centerY.equalTo(self.backButton);
|
||||||
|
make.left.equalTo(self.backButton.mas_right).offset(12);
|
||||||
|
make.width.mas_equalTo(315);
|
||||||
|
make.height.mas_equalTo(36);
|
||||||
|
make.right.lessThanOrEqualTo(self.topBar).offset(-16);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.searchBarView.mas_bottom).offset(12);
|
make.top.equalTo(self.topBar.mas_bottom).offset(12);
|
||||||
make.left.right.bottom.equalTo(self.view);
|
make.left.right.bottom.equalTo(self.view);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
@@ -62,6 +71,19 @@ static NSString * const kResultCellId = @"KBSkinCardCell";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)viewWillAppear:(BOOL)animated {
|
||||||
|
[super viewWillAppear:animated];
|
||||||
|
// 隐藏系统导航栏
|
||||||
|
[self.navigationController setNavigationBarHidden:YES animated:animated];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewWillDisappear:(BOOL)animated {
|
||||||
|
[super viewWillDisappear:animated];
|
||||||
|
if (self.isMovingFromParentViewController || self.isBeingDismissed) {
|
||||||
|
[self.navigationController setNavigationBarHidden:NO animated:animated];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
|
|
||||||
/// 执行搜索(示例:本地生成一些数据)
|
/// 执行搜索(示例:本地生成一些数据)
|
||||||
@@ -138,6 +160,35 @@ static NSString * const kResultCellId = @"KBSkinCardCell";
|
|||||||
return _searchBarView;
|
return _searchBarView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIView *)topBar {
|
||||||
|
if (!_topBar) {
|
||||||
|
_topBar = [[UIView alloc] init];
|
||||||
|
_topBar.backgroundColor = [UIColor whiteColor];
|
||||||
|
}
|
||||||
|
return _topBar;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (UIButton *)backButton {
|
||||||
|
if (!_backButton) {
|
||||||
|
_backButton = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||||
|
UIImage *img = nil;
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
img = [UIImage systemImageNamed:@"chevron.left"];
|
||||||
|
}
|
||||||
|
if (img) {
|
||||||
|
[_backButton setImage:img forState:UIControlStateNormal];
|
||||||
|
} else {
|
||||||
|
[_backButton setTitle:@"<" forState:UIControlStateNormal];
|
||||||
|
_backButton.titleLabel.font = [UIFont systemFontOfSize:22 weight:UIFontWeightSemibold];
|
||||||
|
}
|
||||||
|
[_backButton setTintColor:[UIColor blackColor]];
|
||||||
|
[_backButton addTarget:self action:@selector(onTapBack) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _backButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)onTapBack { [self.navigationController popViewControllerAnimated:YES]; }
|
||||||
|
|
||||||
- (UICollectionViewFlowLayout *)flowLayout {
|
- (UICollectionViewFlowLayout *)flowLayout {
|
||||||
if (!_flowLayout) {
|
if (!_flowLayout) {
|
||||||
_flowLayout = [[UICollectionViewFlowLayout alloc] init];
|
_flowLayout = [[UICollectionViewFlowLayout alloc] init];
|
||||||
@@ -166,4 +217,3 @@ static NSString * const kResultCellId = @"KBSkinCardCell";
|
|||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -27,9 +27,10 @@ typedef NS_ENUM(NSInteger, KBSearchSection) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@interface KBSearchVC ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
@interface KBSearchVC ()<UICollectionViewDataSource, UICollectionViewDelegateFlowLayout>
|
||||||
// 顶部搜索栏(封装的 View)——放到导航栏的 titleView 中,Y 轴与返回按钮一致
|
// 自定义顶部区域:返回按钮 + 搜索栏
|
||||||
|
@property (nonatomic, strong) UIView *topBar;
|
||||||
|
@property (nonatomic, strong) UIButton *backButton;
|
||||||
@property (nonatomic, strong) KBSearchBarView *searchBarView;
|
@property (nonatomic, strong) KBSearchBarView *searchBarView;
|
||||||
@property (nonatomic, strong) UIView *titleContainer; // 承载 searchBarView 的容器
|
|
||||||
// 列表
|
// 列表
|
||||||
@property (nonatomic, strong) UICollectionView *collectionView;
|
@property (nonatomic, strong) UICollectionView *collectionView;
|
||||||
@property (nonatomic, strong) UICollectionViewLeftAlignedLayout *flowLayout;
|
@property (nonatomic, strong) UICollectionViewLeftAlignedLayout *flowLayout;
|
||||||
@@ -48,14 +49,35 @@ typedef NS_ENUM(NSInteger, KBSearchSection) {
|
|||||||
self.view.backgroundColor = [UIColor whiteColor];
|
self.view.backgroundColor = [UIColor whiteColor];
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
|
[self.view addSubview:self.topBar];
|
||||||
|
[self.topBar addSubview:self.backButton];
|
||||||
|
[self.topBar addSubview:self.searchBarView];
|
||||||
[self.view addSubview:self.collectionView];
|
[self.view addSubview:self.collectionView];
|
||||||
|
|
||||||
// 将搜索栏放进导航栏 titleView,Y 轴自然与返回按钮对齐
|
// 布局 - Masonry(无导航栏)
|
||||||
self.navigationItem.titleView = self.titleContainer;
|
[self.topBar mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.top.equalTo(self.view.mas_top).offset(KB_STATUSBAR_HEIGHT + 8);
|
||||||
|
make.left.right.equalTo(self.view);
|
||||||
|
make.height.mas_equalTo(44); // 容器高度
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.backButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.left.equalTo(self.topBar).offset(12);
|
||||||
|
make.centerY.equalTo(self.topBar);
|
||||||
|
make.width.mas_equalTo(28);
|
||||||
|
make.height.mas_equalTo(36);
|
||||||
|
}];
|
||||||
|
|
||||||
|
[self.searchBarView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
|
make.centerY.equalTo(self.backButton);
|
||||||
|
make.left.equalTo(self.backButton.mas_right).offset(12);
|
||||||
|
make.width.mas_equalTo(315);
|
||||||
|
make.height.mas_equalTo(36);
|
||||||
|
make.right.lessThanOrEqualTo(self.topBar).offset(-16);
|
||||||
|
}];
|
||||||
|
|
||||||
// 布局 - Masonry(列表顶端紧贴导航栏底部)
|
|
||||||
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
|
[self.collectionView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||||
make.top.equalTo(self.view.mas_top).offset(KB_NAV_TOTAL_HEIGHT + 8);
|
make.top.equalTo(self.topBar.mas_bottom).offset(12);
|
||||||
make.left.right.bottom.equalTo(self.view);
|
make.left.right.bottom.equalTo(self.view);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
@@ -82,6 +104,20 @@ typedef NS_ENUM(NSInteger, KBSearchSection) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)viewWillAppear:(BOOL)animated {
|
||||||
|
[super viewWillAppear:animated];
|
||||||
|
// 隐藏系统导航栏,使用自定义返回按钮
|
||||||
|
[self.navigationController setNavigationBarHidden:YES animated:animated];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewWillDisappear:(BOOL)animated {
|
||||||
|
[super viewWillDisappear:animated];
|
||||||
|
// 仅在返回上一级时恢复导航栏;push 到下一级(同样隐藏导航栏)不做处理,避免闪烁
|
||||||
|
if (self.isMovingFromParentViewController || self.isBeingDismissed) {
|
||||||
|
[self.navigationController setNavigationBarHidden:NO animated:animated];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Private
|
#pragma mark - Private
|
||||||
|
|
||||||
/// 执行搜索:将关键字置顶到历史(去重、忽略大小写/前后空格)
|
/// 执行搜索:将关键字置顶到历史(去重、忽略大小写/前后空格)
|
||||||
@@ -337,30 +373,35 @@ typedef NS_ENUM(NSInteger, KBSearchSection) {
|
|||||||
return _searchBarView;
|
return _searchBarView;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (UIView *)titleContainer {
|
- (UIView *)topBar {
|
||||||
if (!_titleContainer) {
|
if (!_topBar) {
|
||||||
// 固定尺寸:宽 315,高 36(与返回按钮同一 Y 轴,作为 titleView 显示)
|
_topBar = [[UIView alloc] init];
|
||||||
CGFloat width = 315.0;
|
_topBar.backgroundColor = [UIColor whiteColor];
|
||||||
_titleContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, 36.0)];
|
|
||||||
_titleContainer.backgroundColor = [UIColor clearColor];
|
|
||||||
// 告诉导航栏使用 AutoLayout 计算尺寸,并强约束宽高为 315x36
|
|
||||||
_titleContainer.translatesAutoresizingMaskIntoConstraints = NO;
|
|
||||||
[[_titleContainer.widthAnchor constraintEqualToConstant:width] setActive:YES];
|
|
||||||
[[_titleContainer.heightAnchor constraintEqualToConstant:36.0] setActive:YES];
|
|
||||||
[_titleContainer setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
|
|
||||||
[_titleContainer setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
|
|
||||||
|
|
||||||
// 将 searchBarView 塞入容器,充满容器
|
|
||||||
[_titleContainer addSubview:self.searchBarView];
|
|
||||||
[self.searchBarView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
||||||
make.edges.equalTo(_titleContainer);
|
|
||||||
make.height.mas_equalTo(36.0);
|
|
||||||
}];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return _titleContainer;
|
return _topBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIButton *)backButton {
|
||||||
|
if (!_backButton) {
|
||||||
|
_backButton = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||||
|
UIImage *img = nil;
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
img = [UIImage systemImageNamed:@"chevron.left"];
|
||||||
|
}
|
||||||
|
if (img) {
|
||||||
|
[_backButton setImage:img forState:UIControlStateNormal];
|
||||||
|
} else {
|
||||||
|
[_backButton setTitle:@"<" forState:UIControlStateNormal];
|
||||||
|
_backButton.titleLabel.font = [UIFont systemFontOfSize:22 weight:UIFontWeightSemibold];
|
||||||
|
}
|
||||||
|
[_backButton setTintColor:[UIColor blackColor]];
|
||||||
|
[_backButton addTarget:self action:@selector(onTapBack) forControlEvents:UIControlEventTouchUpInside];
|
||||||
|
}
|
||||||
|
return _backButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)onTapBack { [self.navigationController popViewControllerAnimated:YES]; }
|
||||||
|
|
||||||
- (UICollectionViewLeftAlignedLayout *)flowLayout {
|
- (UICollectionViewLeftAlignedLayout *)flowLayout {
|
||||||
if (!_flowLayout) {
|
if (!_flowLayout) {
|
||||||
_flowLayout = [[UICollectionViewLeftAlignedLayout alloc] init];
|
_flowLayout = [[UICollectionViewLeftAlignedLayout alloc] init];
|
||||||
|
|||||||
Reference in New Issue
Block a user