// // KBKeyBoardMainView.m // CustomKeyboard // // Created by Mac on 2025/10/28. // #import "KBKeyBoardMainView.h" #import "KBToolBar.h" #import "KBKeyboardView.h" #import "KBFunctionView.h" #import "KBKey.h" #import "KBEmojiPanelView.h" #import "Masonry.h" #import "KBSkinManager.h" @interface KBKeyBoardMainView () @property (nonatomic, strong) KBToolBar *topBar; @property (nonatomic, strong) KBKeyboardView *keyboardView; @property (nonatomic, strong) KBEmojiPanelView *emojiView; @property (nonatomic, assign) BOOL emojiPanelVisible; // 注意:功能面板的展示/隐藏由外部控制器决定,此处不再直接管理显隐 @end @implementation KBKeyBoardMainView - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.backgroundColor = [KBSkinManager shared].current.keyboardBackground; // 顶部栏 self.topBar = [[KBToolBar alloc] init]; self.topBar.delegate = self; [self addSubview:self.topBar]; // 键盘区域(高度按照设计值做等比缩放,避免不同机型上按键被压缩/拉伸) CGFloat keyboardAreaHeight = KBFit(200.0f); CGFloat bottomInset = KBFit(4.0f); CGFloat barSpacing = KBFit(6.0f); self.keyboardView = [[KBKeyboardView alloc] init]; self.keyboardView.delegate = self; [self addSubview:self.keyboardView]; [self.keyboardView mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(self); make.height.mas_equalTo(keyboardAreaHeight); make.bottom.equalTo(self.mas_bottom).offset(-bottomInset); }]; self.emojiView = [[KBEmojiPanelView alloc] init]; self.emojiView.hidden = YES; self.emojiView.alpha = 0.0; self.emojiView.delegate = self; [self addSubview:self.emojiView]; [self.emojiView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self); }]; [self.topBar mas_makeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(self); make.top.equalTo(self.mas_top).offset(0); make.bottom.equalTo(self.keyboardView.mas_top).offset(-barSpacing); }]; // 功能面板切换交由外部控制器处理;此处不直接创建/管理 } return self; } - (void)setEmojiPanelVisible:(BOOL)visible animated:(BOOL)animated { if (self.emojiPanelVisible == visible) return; self.emojiPanelVisible = visible; if (visible) { [self.emojiView reloadData]; self.emojiView.hidden = NO; [self bringSubviewToFront:self.emojiView]; } else { self.keyboardView.hidden = NO; self.topBar.hidden = NO; } void (^changes)(void) = ^{ self.emojiView.alpha = visible ? 1.0 : 0.0; self.keyboardView.alpha = visible ? 0.0 : 1.0; self.topBar.alpha = visible ? 0.0 : 1.0; }; void (^completion)(BOOL) = ^(BOOL finished) { self.emojiView.hidden = !visible; self.keyboardView.hidden = visible; self.topBar.hidden = visible; }; if (animated) { [UIView animateWithDuration:0.22 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:changes completion:completion]; } else { changes(); completion(YES); } } - (void)toggleEmojiPanel { [self setEmojiPanelVisible:!self.emojiPanelVisible animated:YES]; } #pragma mark - KBToolBarDelegate - (void)toolBar:(KBToolBar *)toolBar didTapActionAtIndex:(NSInteger)index { // 将事件抛给外部控制器,由其决定是否切换到功能面板 if ([self.delegate respondsToSelector:@selector(keyBoardMainView:didTapToolActionAtIndex:)]) { [self.delegate keyBoardMainView:self didTapToolActionAtIndex:index]; } } - (void)toolBarDidTapSettings:(KBToolBar *)toolBar { if ([self.delegate respondsToSelector:@selector(keyBoardMainViewDidTapSettings:)]) { [self.delegate keyBoardMainViewDidTapSettings:self]; } } - (void)toolBarDidTapUndo:(KBToolBar *)toolBar { if ([self.delegate respondsToSelector:@selector(keyBoardMainViewDidTapUndo:)]) { [self.delegate keyBoardMainViewDidTapUndo:self]; } } #pragma mark - KBKeyboardViewDelegate - (void)keyboardView:(KBKeyboardView *)keyboard didTapKey:(KBKey *)key { switch (key.type) { case KBKeyTypeCharacter: // 文本插入交由上层控制器处理 if ([self.delegate respondsToSelector:@selector(keyBoardMainView:didTapKey:)]) { [self.delegate keyBoardMainView:self didTapKey:key]; } break; case KBKeyTypeBackspace: if ([self.delegate respondsToSelector:@selector(keyBoardMainView:didTapKey:)]) { [self.delegate keyBoardMainView:self didTapKey:key]; } break; case KBKeyTypeSpace: if ([self.delegate respondsToSelector:@selector(keyBoardMainView:didTapKey:)]) { [self.delegate keyBoardMainView:self didTapKey:key]; } break; case KBKeyTypeReturn: if ([self.delegate respondsToSelector:@selector(keyBoardMainView:didTapKey:)]) { [self.delegate keyBoardMainView:self didTapKey:key]; } break; case KBKeyTypeModeChange: { // 切换 字母 <-> 数字 布局 keyboard.layoutStyle = (keyboard.layoutStyle == KBKeyboardLayoutStyleLetters) ? KBKeyboardLayoutStyleNumbers : KBKeyboardLayoutStyleLetters; [keyboard reloadKeys]; } break; case KBKeyTypeGlobe: if ([self.delegate respondsToSelector:@selector(keyBoardMainView:didTapKey:)]) { [self.delegate keyBoardMainView:self didTapKey:key]; } break; case KBKeyTypeCustom: { if ([key.identifier isEqualToString:KBKeyIdentifierEmojiPanel]) { [self toggleEmojiPanel]; break; } if ([self.delegate respondsToSelector:@selector(keyBoardMainView:didTapKey:)]) { [self.delegate keyBoardMainView:self didTapKey:key]; } } break; case KBKeyTypeShift: // Shift 已在 KBKeyboardView 内部处理 break; } } // 切换功能面板交由外部控制器处理(此处不再实现) // 设置页展示改由 KeyboardViewController 统一处理 #pragma mark - KBEmojiPanelViewDelegate - (void)emojiPanelView:(KBEmojiPanelView *)panel didSelectEmoji:(NSString *)emoji { if (emoji.length == 0) return; if ([self.delegate respondsToSelector:@selector(keyBoardMainView:didSelectEmoji:)]) { [self.delegate keyBoardMainView:self didSelectEmoji:emoji]; } } - (void)emojiPanelViewDidRequestClose:(KBEmojiPanelView *)panel { [self setEmojiPanelVisible:NO animated:YES]; } - (void)emojiPanelViewDidTapSearch:(KBEmojiPanelView *)panel { if ([self.delegate respondsToSelector:@selector(keyBoardMainViewDidTapEmojiSearch:)]) { [self.delegate keyBoardMainViewDidTapEmojiSearch:self]; } } - (void)emojiPanelViewDidTapDelete:(KBEmojiPanelView *)panel { if ([self.delegate respondsToSelector:@selector(keyBoardMainView:didTapKey:)]) { KBKey *backspace = [KBKey keyWithTitle:@"" type:KBKeyTypeBackspace]; [self.delegate keyBoardMainView:self didTapKey:backspace]; } } #pragma mark - Theme - (void)kb_applyTheme { KBSkinManager *mgr = [KBSkinManager shared]; BOOL hasImg = ([mgr currentBackgroundImage] != nil); UIColor *bg = mgr.current.keyboardBackground; self.backgroundColor = hasImg ? [UIColor clearColor] : bg; self.keyboardView.backgroundColor = hasImg ? [UIColor clearColor] : bg; if ([self.topBar respondsToSelector:@selector(kb_applyTheme)]) { [self.topBar kb_applyTheme]; } [self.keyboardView reloadKeys]; if (self.emojiView) { [self.emojiView applyTheme:mgr.current]; } } @end