添加渐变色
This commit is contained in:
@@ -21,6 +21,10 @@
|
||||
@property(nonatomic, strong) UILabel *statusLabel;
|
||||
@property(nonatomic, strong) UIButton *commentButton;
|
||||
@property(nonatomic, strong) KBAICommentView *commentView;
|
||||
@property(nonatomic, strong) UIView *tabbarBackgroundView;
|
||||
@property(nonatomic, strong) UIVisualEffectView *blurEffectView;
|
||||
@property(nonatomic, strong) CAGradientLayer *gradientLayer;
|
||||
@property(nonatomic, strong) UIImageView *personImageView;
|
||||
|
||||
// 核心模块
|
||||
@property(nonatomic, strong) ConversationOrchestrator *orchestrator;
|
||||
@@ -34,6 +38,10 @@
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
// 让视图延伸到屏幕边缘(包括状态栏和导航栏下方)
|
||||
self.edgesForExtendedLayout = UIRectEdgeAll;
|
||||
self.extendedLayoutIncludesOpaqueBars = YES;
|
||||
|
||||
[self setupUI];
|
||||
[self setupOrchestrator];
|
||||
}
|
||||
@@ -45,6 +53,54 @@
|
||||
[self.orchestrator stop];
|
||||
}
|
||||
|
||||
- (void)viewDidLayoutSubviews {
|
||||
[super viewDidLayoutSubviews];
|
||||
|
||||
// 设置黑色渐变层(从底部到顶部,黑色到透明)
|
||||
if (!self.gradientLayer) {
|
||||
self.gradientLayer = [CAGradientLayer layer];
|
||||
self.gradientLayer.startPoint = CGPointMake(0.53, 1); // 底部
|
||||
self.gradientLayer.endPoint = CGPointMake(0.54, 0); // 顶部
|
||||
// 渐变颜色:从黑色 24% 不透明度到透明
|
||||
self.gradientLayer.colors = @[
|
||||
(__bridge id)[UIColor colorWithRed:0 / 255.0
|
||||
green:0 / 255.0
|
||||
blue:0 / 255.0
|
||||
alpha:0.24]
|
||||
.CGColor,
|
||||
(__bridge id)[UIColor colorWithRed:3 / 255.0
|
||||
green:3 / 255.0
|
||||
blue:3 / 255.0
|
||||
alpha:0]
|
||||
.CGColor
|
||||
];
|
||||
self.gradientLayer.locations = @[ @(0.7), @(1.0) ];
|
||||
[self.tabbarBackgroundView.layer addSublayer:self.gradientLayer];
|
||||
}
|
||||
|
||||
// 更新黑色渐变层的 frame
|
||||
self.gradientLayer.frame = self.tabbarBackgroundView.bounds;
|
||||
|
||||
// 为 blurEffectView 添加透明度渐变
|
||||
// mask(从底部到中间不透明,从中间到顶部透明)
|
||||
if (!self.blurEffectView.layer.mask) {
|
||||
CAGradientLayer *maskLayer = [CAGradientLayer layer];
|
||||
maskLayer.startPoint = CGPointMake(0.5, 1); // 底部
|
||||
maskLayer.endPoint = CGPointMake(0.5, 0); // 顶部
|
||||
// 底部到中间保持不透明,从中间到顶部过渡透明
|
||||
maskLayer.colors = @[
|
||||
(__bridge id)[UIColor whiteColor].CGColor, // 底部:完全不透明
|
||||
(__bridge id)[UIColor whiteColor].CGColor, // 中间:完全不透明
|
||||
(__bridge id)[UIColor clearColor].CGColor // 顶部:完全透明
|
||||
];
|
||||
maskLayer.locations = @[ @(0.0), @(0.5), @(1.0) ];
|
||||
self.blurEffectView.layer.mask = maskLayer;
|
||||
}
|
||||
|
||||
// 更新 mask 的 frame
|
||||
self.blurEffectView.layer.mask.frame = self.blurEffectView.bounds;
|
||||
}
|
||||
|
||||
#pragma mark - UI Setup
|
||||
|
||||
- (void)setupUI {
|
||||
@@ -54,6 +110,29 @@
|
||||
// 安全区域
|
||||
UILayoutGuide *safeArea = self.view.safeAreaLayoutGuide;
|
||||
|
||||
// PersonImageView(背景图,最底层)
|
||||
self.personImageView =
|
||||
[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"person_icon"]];
|
||||
[self.view addSubview:self.personImageView];
|
||||
[self.personImageView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.right.top.bottom.equalTo(self.view);
|
||||
}];
|
||||
|
||||
// TabBar 毛玻璃模糊背景(在 personImageView 之上)
|
||||
self.tabbarBackgroundView = [[UIView alloc] init];
|
||||
self.tabbarBackgroundView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
self.tabbarBackgroundView.clipsToBounds = YES;
|
||||
[self.view addSubview:self.tabbarBackgroundView];
|
||||
|
||||
// 模糊效果
|
||||
UIBlurEffect *blurEffect =
|
||||
[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
|
||||
self.blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
|
||||
self.blurEffectView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self.tabbarBackgroundView addSubview:self.blurEffectView];
|
||||
|
||||
// 渐变层将在 viewDidLayoutSubviews 中设置
|
||||
|
||||
// 状态标签
|
||||
self.statusLabel = [[UILabel alloc] init];
|
||||
self.statusLabel.text = @"按住按钮开始对话";
|
||||
@@ -64,10 +143,10 @@
|
||||
[self.view addSubview:self.statusLabel];
|
||||
|
||||
// 聊天视图
|
||||
self.chatView = [[KBAiChatView alloc] init];
|
||||
self.chatView.backgroundColor = [UIColor systemBackgroundColor];
|
||||
self.chatView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self.view addSubview:self.chatView];
|
||||
// self.chatView = [[KBAiChatView alloc] init];
|
||||
// self.chatView.backgroundColor = [UIColor systemBackgroundColor];
|
||||
// self.chatView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
// [self.view addSubview:self.chatView];
|
||||
|
||||
// 录音按钮
|
||||
self.recordButton = [[KBAiRecordButton alloc] init];
|
||||
@@ -92,51 +171,34 @@
|
||||
forControlEvents:UIControlEventTouchUpInside];
|
||||
[self.view addSubview:self.commentButton];
|
||||
|
||||
// 布局约束
|
||||
[NSLayoutConstraint activateConstraints:@[
|
||||
// 状态标签
|
||||
[self.statusLabel.topAnchor constraintEqualToAnchor:safeArea.topAnchor
|
||||
constant:8],
|
||||
[self.statusLabel.leadingAnchor
|
||||
constraintEqualToAnchor:safeArea.leadingAnchor
|
||||
constant:16],
|
||||
[self.statusLabel.trailingAnchor
|
||||
constraintEqualToAnchor:safeArea.trailingAnchor
|
||||
constant:-16],
|
||||
// 布局约束 - 使用 Masonry
|
||||
[self.tabbarBackgroundView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.right.bottom.equalTo(self.view);
|
||||
make.height.mas_equalTo(KBFit(238));
|
||||
}];
|
||||
|
||||
// 聊天视图
|
||||
[self.chatView.topAnchor
|
||||
constraintEqualToAnchor:self.statusLabel.bottomAnchor
|
||||
constant:8],
|
||||
[self.chatView.leadingAnchor
|
||||
constraintEqualToAnchor:safeArea.leadingAnchor],
|
||||
[self.chatView.trailingAnchor
|
||||
constraintEqualToAnchor:safeArea.trailingAnchor],
|
||||
[self.chatView.bottomAnchor
|
||||
constraintEqualToAnchor:self.recordButton.topAnchor
|
||||
constant:-16],
|
||||
[self.blurEffectView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.edges.equalTo(self.tabbarBackgroundView);
|
||||
}];
|
||||
|
||||
// 录音按钮
|
||||
[self.recordButton.leadingAnchor
|
||||
constraintEqualToAnchor:safeArea.leadingAnchor
|
||||
constant:20],
|
||||
[self.recordButton.trailingAnchor
|
||||
constraintEqualToAnchor:safeArea.trailingAnchor
|
||||
constant:-20],
|
||||
[self.recordButton.bottomAnchor
|
||||
constraintEqualToAnchor:safeArea.bottomAnchor
|
||||
constant:-16],
|
||||
[self.recordButton.heightAnchor constraintEqualToConstant:50],
|
||||
[self.statusLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop).offset(8);
|
||||
make.left.equalTo(self.view).offset(16);
|
||||
make.right.equalTo(self.view).offset(-16);
|
||||
}];
|
||||
|
||||
// 评论按钮(右侧居中)
|
||||
[self.commentButton.trailingAnchor
|
||||
constraintEqualToAnchor:safeArea.trailingAnchor
|
||||
constant:-16],
|
||||
[self.commentButton.centerYAnchor
|
||||
constraintEqualToAnchor:self.chatView.centerYAnchor],
|
||||
[self.commentButton.widthAnchor constraintEqualToConstant:50],
|
||||
[self.commentButton.heightAnchor constraintEqualToConstant:50],
|
||||
]];
|
||||
[self.recordButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.left.equalTo(self.view.mas_safeAreaLayoutGuideLeft).offset(20);
|
||||
make.right.equalTo(self.view.mas_safeAreaLayoutGuideRight).offset(-20);
|
||||
make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).offset(-16);
|
||||
make.height.mas_equalTo(50);
|
||||
}];
|
||||
|
||||
[self.commentButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
||||
make.right.equalTo(self.view.mas_safeAreaLayoutGuideRight).offset(-16);
|
||||
make.centerY.equalTo(self.view);
|
||||
make.width.height.mas_equalTo(50);
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Orchestrator Setup
|
||||
@@ -240,25 +302,25 @@
|
||||
|
||||
#pragma mark - 事件
|
||||
- (void)showComment {
|
||||
CGFloat customViewHeight = KB_SCREEN_HEIGHT * (0.8);
|
||||
KBAICommentView *customView = [[KBAICommentView alloc]
|
||||
initWithFrame:CGRectMake(0, 0, KB_SCREEN_WIDTH, customViewHeight)];
|
||||
LSTPopView *popView =
|
||||
[LSTPopView initWithCustomView:customView
|
||||
parentView:nil
|
||||
popStyle:LSTPopStyleSmoothFromBottom
|
||||
dismissStyle:LSTDismissStyleSmoothToBottom];
|
||||
self.popView = popView;
|
||||
popView.priority = 1000;
|
||||
popView.isAvoidKeyboard = false;
|
||||
popView.hemStyle = LSTHemStyleBottom;
|
||||
popView.dragStyle = LSTDragStyleY_Positive;
|
||||
popView.dragDistance = customViewHeight * 0.5;
|
||||
popView.sweepStyle = LSTSweepStyleY_Positive;
|
||||
popView.swipeVelocity = 1600;
|
||||
popView.sweepDismissStyle = LSTSweepDismissStyleSmooth;
|
||||
|
||||
[popView pop];
|
||||
CGFloat customViewHeight = KB_SCREEN_HEIGHT * (0.8);
|
||||
KBAICommentView *customView = [[KBAICommentView alloc]
|
||||
initWithFrame:CGRectMake(0, 0, KB_SCREEN_WIDTH, customViewHeight)];
|
||||
LSTPopView *popView =
|
||||
[LSTPopView initWithCustomView:customView
|
||||
parentView:nil
|
||||
popStyle:LSTPopStyleSmoothFromBottom
|
||||
dismissStyle:LSTDismissStyleSmoothToBottom];
|
||||
self.popView = popView;
|
||||
popView.priority = 1000;
|
||||
popView.isAvoidKeyboard = false;
|
||||
popView.hemStyle = LSTHemStyleBottom;
|
||||
popView.dragStyle = LSTDragStyleY_Positive;
|
||||
popView.dragDistance = customViewHeight * 0.5;
|
||||
popView.sweepStyle = LSTSweepStyleY_Positive;
|
||||
popView.swipeVelocity = 1600;
|
||||
popView.sweepDismissStyle = LSTSweepDismissStyleSmooth;
|
||||
|
||||
[popView pop];
|
||||
}
|
||||
|
||||
- (void)showCommentDirectly {
|
||||
@@ -268,12 +330,14 @@
|
||||
}
|
||||
|
||||
CGFloat customViewHeight = KB_SCREEN_HEIGHT * (0.8);
|
||||
KBAICommentView *customView = [[KBAICommentView alloc] initWithFrame:CGRectZero];
|
||||
KBAICommentView *customView =
|
||||
[[KBAICommentView alloc] initWithFrame:CGRectZero];
|
||||
customView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self.view addSubview:customView];
|
||||
[NSLayoutConstraint activateConstraints:@[
|
||||
[customView.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor],
|
||||
[customView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor],
|
||||
[customView.trailingAnchor
|
||||
constraintEqualToAnchor:self.view.trailingAnchor],
|
||||
[customView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor],
|
||||
[customView.heightAnchor constraintEqualToConstant:customViewHeight],
|
||||
]];
|
||||
|
||||
Reference in New Issue
Block a user