2
This commit is contained in:
@@ -7,9 +7,24 @@
|
||||
|
||||
#import "HomeSheetVC.h"
|
||||
#import "KBDirectionIndicatorView.h"
|
||||
// 子控制器
|
||||
#import "HomeHotVC.h"
|
||||
#import "HomeRankVC.h"
|
||||
|
||||
@interface HomeSheetVC ()
|
||||
@property (nonatomic, strong) KBDirectionIndicatorView *indicator;
|
||||
|
||||
// 顶部切换按钮与指示条
|
||||
@property (nonatomic, strong) UIView *topBar;
|
||||
@property (nonatomic, strong) UIButton *hotButton;
|
||||
@property (nonatomic, strong) UIButton *rankButton;
|
||||
@property (nonatomic, strong) UIView *underlineView; // 选中下划线
|
||||
|
||||
// 承载子控制器内容
|
||||
@property (nonatomic, strong) UIView *containerView;
|
||||
@property (nonatomic, strong) UIViewController *currentChild;
|
||||
@property (nonatomic, strong) HomeHotVC *hotVC;
|
||||
@property (nonatomic, strong) HomeRankVC *rankVC;
|
||||
@end
|
||||
|
||||
@implementation HomeSheetVC
|
||||
@@ -22,6 +37,11 @@
|
||||
config = [HWBackgroundConfig configWithBehavior:HWBackgroundBehaviorDefault];
|
||||
config.backgroundAlpha = 0.01;
|
||||
[self.hw_dimmedView reloadConfig:config];
|
||||
|
||||
// 顶部按钮 + 容器
|
||||
[self setupTopButtonsAndContainer];
|
||||
// 默认展示“热门”
|
||||
[self switchToIndex:0 animated:NO];
|
||||
}
|
||||
|
||||
- (UIView<HWPanModalIndicatorProtocol> *)customIndicatorView {
|
||||
@@ -32,6 +52,13 @@
|
||||
- (void)panModalTransitionDidFinish {
|
||||
// 初次展示后按当前状态设定一次朝向
|
||||
[self.indicator applyPresentationState:self.hw_presentationState];
|
||||
// 避免出现内容随弹窗上移的“位移动画”观感:
|
||||
// 顶部栏在展示动画期间先隐藏,待完成后淡入
|
||||
if (self.topBar && self.topBar.alpha < 1.0) {
|
||||
[UIView animateWithDuration:0.18 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
|
||||
self.topBar.alpha = 1.0;
|
||||
} completion:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didChangeTransitionToState:(PresentationState)state {
|
||||
@@ -77,5 +104,157 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
// 出现时不做上推动画(瞬时到位)
|
||||
- (NSTimeInterval)transitionDuration {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 可选:关闭触觉反馈,避免出现时的轻微震动
|
||||
- (BOOL)isHapticFeedbackEnabled {
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - UI
|
||||
|
||||
- (void)setupTopButtonsAndContainer {
|
||||
// 顶部栏
|
||||
self.topBar = [[UIView alloc] init];
|
||||
self.topBar.backgroundColor = [UIColor colorWithWhite:1 alpha:0.9];
|
||||
[self.view addSubview:self.topBar];
|
||||
// 首次展示时先隐藏,待转场完成后再淡入,避免“自底向上滑入”的错觉
|
||||
self.topBar.alpha = 0.0;
|
||||
|
||||
// 两个按钮
|
||||
self.hotButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[self.hotButton setTitle:@"热门" forState:UIControlStateNormal];
|
||||
[self.hotButton setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal];
|
||||
[self.hotButton setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
|
||||
self.hotButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
|
||||
self.hotButton.tag = 0;
|
||||
[self.hotButton addTarget:self action:@selector(onTapTopButton:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self.topBar addSubview:self.hotButton];
|
||||
|
||||
self.rankButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
||||
[self.rankButton setTitle:@"排行" forState:UIControlStateNormal];
|
||||
[self.rankButton setTitleColor:[UIColor darkTextColor] forState:UIControlStateNormal];
|
||||
[self.rankButton setTitleColor:[UIColor blackColor] forState:UIControlStateSelected];
|
||||
self.rankButton.titleLabel.font = [UIFont boldSystemFontOfSize:16];
|
||||
self.rankButton.tag = 1;
|
||||
[self.rankButton addTarget:self action:@selector(onTapTopButton:) forControlEvents:UIControlEventTouchUpInside];
|
||||
[self.topBar addSubview:self.rankButton];
|
||||
|
||||
// 下划线(跟随选中按钮)
|
||||
self.underlineView = [[UIView alloc] init];
|
||||
self.underlineView.backgroundColor = [UIColor blackColor];
|
||||
self.underlineView.layer.cornerRadius = 1.0;
|
||||
[self.topBar addSubview:self.underlineView];
|
||||
|
||||
// 容器视图
|
||||
self.containerView = [[UIView alloc] init];
|
||||
self.containerView.backgroundColor = [UIColor whiteColor];
|
||||
self.containerView.clipsToBounds = YES;
|
||||
[self.view addSubview:self.containerView];
|
||||
|
||||
// Masonry 约束
|
||||
CGFloat topPadding = 12; // 与顶部小指示器留点空间
|
||||
[self.topBar mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.right.equalTo(self.view);
|
||||
make.top.equalTo(self.view).offset(topPadding);
|
||||
make.height.mas_equalTo(44);
|
||||
}];
|
||||
|
||||
[self.hotButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.bottom.equalTo(self.topBar);
|
||||
make.left.equalTo(self.topBar);
|
||||
}];
|
||||
[self.rankButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.bottom.equalTo(self.topBar);
|
||||
make.right.equalTo(self.topBar);
|
||||
make.left.equalTo(self.hotButton.mas_right);
|
||||
make.width.equalTo(self.hotButton);
|
||||
}];
|
||||
|
||||
// 初始先放在“热门”下方,宽度稍小于按钮文字
|
||||
[self.underlineView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.height.mas_equalTo(2);
|
||||
make.bottom.equalTo(self.topBar.mas_bottom).offset(-2);
|
||||
make.centerX.equalTo(self.hotButton);
|
||||
make.width.mas_equalTo(24);
|
||||
}];
|
||||
|
||||
[self.containerView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.equalTo(self.topBar.mas_bottom).offset(8);
|
||||
make.left.right.bottom.equalTo(self.view);
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Action
|
||||
|
||||
- (void)onTapTopButton:(UIButton *)sender {
|
||||
[self switchToIndex:sender.tag animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - Switch Child
|
||||
|
||||
- (void)switchToIndex:(NSInteger)index animated:(BOOL)animated {
|
||||
UIViewController *target = (index == 0) ? self.hotVC : self.rankVC;
|
||||
if (!target) {
|
||||
if (index == 0) {
|
||||
self.hotVC = [HomeHotVC new];
|
||||
target = self.hotVC;
|
||||
} else {
|
||||
self.rankVC = [HomeRankVC new];
|
||||
target = self.rankVC;
|
||||
}
|
||||
}
|
||||
|
||||
if (self.currentChild == target) {
|
||||
// 已经是目标
|
||||
[self updateButtonStateForIndex:index animated:animated];
|
||||
return;
|
||||
}
|
||||
|
||||
// 移除当前
|
||||
if (self.currentChild) {
|
||||
[self.currentChild willMoveToParentViewController:nil];
|
||||
[self.currentChild.view removeFromSuperview];
|
||||
[self.currentChild removeFromParentViewController];
|
||||
}
|
||||
|
||||
// 添加目标
|
||||
[self addChildViewController:target];
|
||||
[self.containerView addSubview:target.view];
|
||||
target.view.backgroundColor = [UIColor colorWithWhite:0.98 alpha:1];
|
||||
[target.view mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.equalTo(self.containerView);
|
||||
}];
|
||||
[target didMoveToParentViewController:self];
|
||||
self.currentChild = target;
|
||||
|
||||
[self updateButtonStateForIndex:index animated:animated];
|
||||
}
|
||||
|
||||
- (void)updateButtonStateForIndex:(NSInteger)index animated:(BOOL)animated {
|
||||
self.hotButton.selected = (index == 0);
|
||||
self.rankButton.selected = (index == 1);
|
||||
|
||||
UIButton *btn = (index == 0) ? self.hotButton : self.rankButton;
|
||||
// 更新下划线位置
|
||||
[self.underlineView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.height.mas_equalTo(2);
|
||||
make.bottom.equalTo(self.topBar.mas_bottom).offset(-2);
|
||||
make.centerX.equalTo(btn);
|
||||
make.width.mas_equalTo(24);
|
||||
}];
|
||||
|
||||
if (animated) {
|
||||
[UIView animateWithDuration:0.25 animations:^{
|
||||
[self.topBar layoutIfNeeded];
|
||||
}];
|
||||
} else {
|
||||
[self.topBar layoutIfNeeded];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user