2025-11-27 15:34:33 +08:00
|
|
|
|
//
|
|
|
|
|
|
// KBKeyboardMaskView.m
|
|
|
|
|
|
// keyBoard
|
|
|
|
|
|
//
|
|
|
|
|
|
// Created by Mac on 2025/11/27.
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
#import "KBKeyboardMaskView.h"
|
|
|
|
|
|
|
|
|
|
|
|
@interface KBKeyboardMaskView ()
|
|
|
|
|
|
@property (nonatomic, strong) UIButton *backButton;
|
|
|
|
|
|
@property (nonatomic, strong) FLAnimatedImageView *gifView;
|
|
|
|
|
|
@property (nonatomic, assign) CGFloat keyboardHeight;
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
@implementation KBKeyboardMaskView
|
|
|
|
|
|
|
|
|
|
|
|
- (instancetype)initWithFrame:(CGRect)frame {
|
|
|
|
|
|
self = [super initWithFrame:frame];
|
|
|
|
|
|
if (!self) return nil;
|
2025-11-27 19:20:20 +08:00
|
|
|
|
self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
|
2025-11-27 15:34:33 +08:00
|
|
|
|
self.userInteractionEnabled = YES;
|
|
|
|
|
|
|
|
|
|
|
|
// 返回按钮
|
|
|
|
|
|
_backButton = [UIButton buttonWithType:UIButtonTypeCustom];
|
|
|
|
|
|
UIImage *backImg = [UIImage imageNamed:@"close_white2_icon"];
|
|
|
|
|
|
[_backButton setImage:backImg forState:UIControlStateNormal];
|
|
|
|
|
|
[self addSubview:_backButton];
|
|
|
|
|
|
|
|
|
|
|
|
[_backButton mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
|
|
make.left.equalTo(self).offset(9);
|
|
|
|
|
|
if (@available(iOS 11.0, *)) {
|
|
|
|
|
|
make.top.equalTo(self.mas_safeAreaLayoutGuideTop).offset(4);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
make.top.equalTo(self).offset(40);
|
|
|
|
|
|
}
|
|
|
|
|
|
make.width.height.mas_equalTo(40);
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
// GIF 区域
|
|
|
|
|
|
_gifView = [FLAnimatedImageView new];
|
|
|
|
|
|
_gifView.contentMode = UIViewContentModeScaleAspectFit;
|
|
|
|
|
|
_gifView.clipsToBounds = YES;
|
|
|
|
|
|
[self addSubview:_gifView];
|
|
|
|
|
|
|
|
|
|
|
|
// 尺寸固定:宽=屏幕宽,高=300;位置在 layoutSubviews 里根据键盘高度动态计算
|
|
|
|
|
|
CGFloat screenW = UIScreen.mainScreen.bounds.size.width;
|
|
|
|
|
|
[_gifView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
|
|
make.centerX.equalTo(self);
|
2025-11-27 19:20:20 +08:00
|
|
|
|
make.width.mas_equalTo(KBFit(316));
|
|
|
|
|
|
make.height.mas_equalTo(KBFit(209));
|
2025-11-27 15:34:33 +08:00
|
|
|
|
// 竖直方向不在这里约束,由 layoutSubviews 手动布局
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
// 整个蒙层点击:激活输入框
|
|
|
|
|
|
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onTapMask:)];
|
|
|
|
|
|
[self addGestureRecognizer:tap];
|
|
|
|
|
|
|
|
|
|
|
|
// 加载 GIF 资源(占位名,可按需更换为实际文件名)
|
|
|
|
|
|
NSString *gifPath = [[NSBundle mainBundle] pathForResource:@"kb_guide_keyboard" ofType:@"gif"];
|
|
|
|
|
|
if (gifPath.length > 0) {
|
|
|
|
|
|
NSData *data = [NSData dataWithContentsOfFile:gifPath];
|
|
|
|
|
|
if (data.length > 0) {
|
|
|
|
|
|
FLAnimatedImage *img = [FLAnimatedImage animatedImageWithGIFData:data];
|
|
|
|
|
|
_gifView.animatedImage = img;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return self;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)layoutSubviews {
|
|
|
|
|
|
[super layoutSubviews];
|
|
|
|
|
|
|
|
|
|
|
|
// 根据键盘高度,保证 GIF 不被遮挡:
|
|
|
|
|
|
// - 无键盘:居中显示;
|
|
|
|
|
|
// - 有键盘:底部距离键盘上方 20pt,若空间不足则向上顶到顶部预留的 safe 区域。
|
|
|
|
|
|
CGFloat viewH = CGRectGetHeight(self.bounds);
|
|
|
|
|
|
CGFloat gifH = 300.0;
|
|
|
|
|
|
CGFloat topMargin = 80.0; // 预留给返回按钮和标题等
|
|
|
|
|
|
CGFloat bottomMargin = 20.0;
|
|
|
|
|
|
|
|
|
|
|
|
CGFloat y = 0;
|
|
|
|
|
|
if (self.keyboardHeight <= 0) {
|
|
|
|
|
|
// 无键盘:垂直居中
|
|
|
|
|
|
y = (viewH - gifH) * 0.5;
|
|
|
|
|
|
if (y < topMargin) y = topMargin;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
CGFloat maxBottom = viewH - self.keyboardHeight - bottomMargin;
|
|
|
|
|
|
y = maxBottom - gifH;
|
|
|
|
|
|
if (y < topMargin) y = topMargin;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CGRect frame = self.gifView.frame;
|
|
|
|
|
|
frame.origin.y = y;
|
|
|
|
|
|
self.gifView.frame = frame;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)onTapMask:(UITapGestureRecognizer *)gr {
|
|
|
|
|
|
CGPoint p = [gr locationInView:self];
|
|
|
|
|
|
// 如果点在返回按钮区域内,则不走 tapHandler(交由按钮自己的事件处理)
|
|
|
|
|
|
if (CGRectContainsPoint(self.backButton.frame, p)) {
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (self.tapHandler) {
|
|
|
|
|
|
self.tapHandler();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)updateForKeyboardHeight:(CGFloat)kbHeight
|
|
|
|
|
|
duration:(NSTimeInterval)duration
|
|
|
|
|
|
curve:(UIViewAnimationOptions)curve {
|
|
|
|
|
|
self.keyboardHeight = MAX(kbHeight, 0);
|
|
|
|
|
|
// 触发布局刷新,以便在 layoutSubviews 里根据最新键盘高度重算 gifView 的 Y 值
|
|
|
|
|
|
[self setNeedsLayout];
|
|
|
|
|
|
[UIView animateWithDuration:duration
|
|
|
|
|
|
delay:0
|
|
|
|
|
|
options:curve
|
|
|
|
|
|
animations:^{
|
|
|
|
|
|
[self layoutIfNeeded];
|
|
|
|
|
|
}
|
|
|
|
|
|
completion:nil];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@end
|