From efdcf60ed1126ba6b731a25aeb3df4473a55396a Mon Sep 17 00:00:00 2001 From: CodeST <694468528@qq.com> Date: Wed, 5 Nov 2025 20:11:10 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E9=9D=9E=E5=88=98=E6=B5=B7=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=9C=B0=E7=90=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CustomKeyboard/View/KBFunctionBarView.m | 67 ++++++++++++++++++++++- CustomKeyboard/View/KBToolBar.m | 70 ++++++++++++++++++++++++- 2 files changed, 135 insertions(+), 2 deletions(-) diff --git a/CustomKeyboard/View/KBFunctionBarView.m b/CustomKeyboard/View/KBFunctionBarView.m index cc8aca9..1121e45 100644 --- a/CustomKeyboard/View/KBFunctionBarView.m +++ b/CustomKeyboard/View/KBFunctionBarView.m @@ -7,12 +7,14 @@ #import "KBFunctionBarView.h" #import "Masonry.h" +#import "KBResponderUtils.h" // 查找 UIInputViewController,用于系统切换输入法 @interface KBFunctionBarView () @property (nonatomic, strong) UIView *leftContainer; // 左侧按钮容器 @property (nonatomic, strong) UIView *rightContainer; // 右侧按钮容器 @property (nonatomic, strong) NSArray *leftButtonsInternal; @property (nonatomic, strong) NSArray *rightButtonsInternal; +@property (nonatomic, strong) UIButton *globeButtonInternal; // 可选:系统“切换输入法”键 @end @implementation KBFunctionBarView @@ -38,6 +40,7 @@ - (void)buildUI { // 左右两个容器,方便分别布局 [self addSubview:self.leftContainer]; + [self addSubview:self.globeButtonInternal]; [self addSubview:self.rightContainer]; [self.rightContainer mas_makeConstraints:^(MASConstraintMaker *make) { @@ -46,8 +49,15 @@ make.height.mas_equalTo(36); }]; - [self.leftContainer mas_makeConstraints:^(MASConstraintMaker *make) { + // 左侧地球键(按需显示) + [self.globeButtonInternal mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.mas_left).offset(12); + make.centerY.equalTo(self.mas_centerY); + make.width.height.mas_equalTo(32); + }]; + + [self.leftContainer mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.globeButtonInternal.mas_right).offset(8); make.right.equalTo(self.rightContainer.mas_left).offset(-12); make.centerY.equalTo(self.mas_centerY); make.height.mas_equalTo(36); @@ -113,6 +123,9 @@ } self.rightButtonsInternal = rightBtns.copy; + + // 初始刷新地球键可见性与事件绑定 + [self kb_refreshGlobeVisibility]; } #pragma mark - Actions @@ -158,4 +171,56 @@ return _rightContainer; } +- (UIButton *)globeButtonInternal { + if (!_globeButtonInternal) { + _globeButtonInternal = [UIButton buttonWithType:UIButtonTypeSystem]; + _globeButtonInternal.layer.cornerRadius = 16; + _globeButtonInternal.layer.masksToBounds = YES; + _globeButtonInternal.backgroundColor = [UIColor colorWithWhite:1 alpha:0.9]; + [_globeButtonInternal setTitle:@"🌐" forState:UIControlStateNormal]; + [_globeButtonInternal setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; + } + return _globeButtonInternal; +} + +#pragma mark - Globe (Input Mode Switch) + +- (void)kb_refreshGlobeVisibility { + UIInputViewController *ivc = KBFindInputViewController(self); + BOOL needSwitchKey = YES; + if (ivc && [ivc respondsToSelector:@selector(needsInputModeSwitchKey)]) { + needSwitchKey = ivc.needsInputModeSwitchKey; + } + + self.globeButtonInternal.hidden = !needSwitchKey; + + // 左容器左约束:根据是否显示地球键动态调整 + [self.leftContainer mas_remakeConstraints:^(MASConstraintMaker *make) { + if (needSwitchKey) { + make.left.equalTo(self.globeButtonInternal.mas_right).offset(8); + } else { + make.left.equalTo(self.mas_left).offset(12); + } + make.right.equalTo(self.rightContainer.mas_left).offset(-12); + make.centerY.equalTo(self.mas_centerY); + make.height.mas_equalTo(36); + }]; + + // 绑定系统输入法切换事件 + [self.globeButtonInternal removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; + if (needSwitchKey && ivc) { + SEL sel = NSSelectorFromString(@"handleInputModeListFromView:withEvent:"); + if ([ivc respondsToSelector:sel]) { + [self.globeButtonInternal addTarget:ivc action:sel forControlEvents:UIControlEventAllTouchEvents]; + } else { + [self.globeButtonInternal addTarget:ivc action:@selector(advanceToNextInputMode) forControlEvents:UIControlEventTouchUpInside]; + } + } +} + +- (void)didMoveToWindow { + [super didMoveToWindow]; + [self kb_refreshGlobeVisibility]; +} + @end diff --git a/CustomKeyboard/View/KBToolBar.m b/CustomKeyboard/View/KBToolBar.m index ab1a602..9158f2e 100644 --- a/CustomKeyboard/View/KBToolBar.m +++ b/CustomKeyboard/View/KBToolBar.m @@ -6,11 +6,13 @@ // #import "KBToolBar.h" +#import "KBResponderUtils.h" // 查找 UIInputViewController,用于系统切换输入法 @interface KBToolBar () @property (nonatomic, strong) UIView *leftContainer; @property (nonatomic, strong) NSArray *leftButtonsInternal; @property (nonatomic, strong) UIButton *settingsButtonInternal; +@property (nonatomic, strong) UIButton *globeButtonInternal; // 可选:系统“切换输入法”键 @end @implementation KBToolBar @@ -50,6 +52,7 @@ - (void)setupUI { [self addSubview:self.leftContainer]; [self addSubview:self.settingsButtonInternal]; + [self addSubview:self.globeButtonInternal]; // 右侧设置按钮 [self.settingsButtonInternal mas_makeConstraints:^(MASConstraintMaker *make) { @@ -58,9 +61,16 @@ make.width.height.mas_equalTo(32); }]; + // 左侧地球键(按需显示) + [self.globeButtonInternal mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.equalTo(self.mas_left).offset(12); + make.centerY.equalTo(self.mas_centerY); + make.width.height.mas_equalTo(32); + }]; + // 左侧容器占用剩余空间 [self.leftContainer mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self.mas_left).offset(12); + make.left.equalTo(self.globeButtonInternal.mas_right).offset(8); make.right.equalTo(self.settingsButtonInternal.mas_left).offset(-12); make.centerY.equalTo(self.mas_centerY); make.height.mas_equalTo(32); @@ -89,6 +99,9 @@ make.right.equalTo(self.leftContainer.mas_right); }]; self.leftButtonsInternal = buttons.copy; + + // 初始刷新地球键的可见性与事件绑定 + [self kb_refreshGlobeVisibility]; } - (UIButton *)buildActionButtonAtIndex:(NSInteger)idx { @@ -142,4 +155,59 @@ return _settingsButtonInternal; } +- (UIButton *)globeButtonInternal { + if (!_globeButtonInternal) { + _globeButtonInternal = [UIButton buttonWithType:UIButtonTypeSystem]; + _globeButtonInternal.layer.cornerRadius = 16; + _globeButtonInternal.layer.masksToBounds = YES; + _globeButtonInternal.backgroundColor = [UIColor colorWithWhite:1 alpha:0.9]; + [_globeButtonInternal setTitle:@"🌐" forState:UIControlStateNormal]; + [_globeButtonInternal setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; + } + return _globeButtonInternal; +} + +#pragma mark - Globe (Input Mode Switch) + +// 根据宿主是否已提供系统切换键,决定是否显示地球按钮;并绑定系统事件。 +- (void)kb_refreshGlobeVisibility { + UIInputViewController *ivc = KBFindInputViewController(self); + BOOL needSwitchKey = YES; + if (ivc && [ivc respondsToSelector:@selector(needsInputModeSwitchKey)]) { + needSwitchKey = ivc.needsInputModeSwitchKey; // YES 表示自定义键盘需要提供切换键 + } + + self.globeButtonInternal.hidden = !needSwitchKey; + + // 重新调整 leftContainer 的左约束:若不需要地球键,则贴左边距 12 + [self.leftContainer mas_remakeConstraints:^(MASConstraintMaker *make) { + if (needSwitchKey) { + make.left.equalTo(self.globeButtonInternal.mas_right).offset(8); + } else { + make.left.equalTo(self.mas_left).offset(12); + } + make.right.equalTo(self.settingsButtonInternal.mas_left).offset(-12); + make.centerY.equalTo(self.mas_centerY); + make.height.mas_equalTo(32); + }]; + + // 绑定系统提供的输入法切换处理(点按切换、长按弹出列表) + // 仅在需要时绑定,避免多余的事件转发 + [self.globeButtonInternal removeTarget:nil action:NULL forControlEvents:UIControlEventAllEvents]; + if (needSwitchKey && ivc) { + SEL sel = NSSelectorFromString(@"handleInputModeListFromView:withEvent:"); + if ([ivc respondsToSelector:sel]) { + [self.globeButtonInternal addTarget:ivc action:sel forControlEvents:UIControlEventAllTouchEvents]; + } else { + // 回退:至少在点按时切换 + [self.globeButtonInternal addTarget:ivc action:@selector(advanceToNextInputMode) forControlEvents:UIControlEventTouchUpInside]; + } + } +} + +- (void)didMoveToWindow { + [super didMoveToWindow]; + [self kb_refreshGlobeVisibility]; +} + @end