// // 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; self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5]; 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); make.width.mas_equalTo(KBFit(316)); make.height.mas_equalTo(KBFit(209)); // 竖直方向不在这里约束,由 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