diff --git a/CustomKeyboard/KeyboardViewController.m b/CustomKeyboard/KeyboardViewController.m index 038e309..2adb859 100644 --- a/CustomKeyboard/KeyboardViewController.m +++ b/CustomKeyboard/KeyboardViewController.m @@ -22,7 +22,7 @@ - (void)kb_consumePendingShopSkin; @end -static CGFloat KEYBOARDHEIGHT = 256 + 20; +static CGFloat KEYBOARDHEIGHT = 200 + 50; static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center, void *observer, @@ -84,10 +84,17 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center, - (void)setupUI { - // 固定键盘整体高度;为减少与系统自调整高度产生的告警,将优先级设置为 High - NSLayoutConstraint *h = [self.view.heightAnchor constraintEqualToConstant:KEYBOARDHEIGHT]; - h.priority = UILayoutPriorityDefaultHigh; // 750 - h.active = YES; + self.view.translatesAutoresizingMaskIntoConstraints = NO; + + CGFloat keyboardHeight = KEYBOARDHEIGHT; // 250 + CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; + + NSLayoutConstraint *h = [self.view.heightAnchor constraintEqualToConstant:keyboardHeight]; + NSLayoutConstraint *w = [self.view.widthAnchor constraintEqualToConstant:screenWidth]; + + h.priority = UILayoutPriorityRequired; + w.priority = UILayoutPriorityRequired; + [NSLayoutConstraint activateConstraints:@[h, w]]; // 关闭 UIInputView 自适应(某些系统版本会尝试放大为全屏高度导致冲突) if ([self.view isKindOfClass:[UIInputView class]]) { UIInputView *iv = (UIInputView *)self.view; @@ -200,7 +207,9 @@ static void KBSkinInstallNotificationCallback(CFNotificationCenterRef center, - (void)keyBoardMainView:(KBKeyBoardMainView *)keyBoardMainView didTapToolActionAtIndex:(NSInteger)index { if (index == 0) { - [self showFunctionPanel:YES]; + /// 充值操作 + [KBHUD showInfo:KBLocalized(@"Recharge Now")]; +// [self showFunctionPanel:YES]; } else { [self showFunctionPanel:NO]; } diff --git a/CustomKeyboard/View/KBKeyBoardMainView.m b/CustomKeyboard/View/KBKeyBoardMainView.m index 0c5dff5..8281d5a 100644 --- a/CustomKeyboard/View/KBKeyBoardMainView.m +++ b/CustomKeyboard/View/KBKeyBoardMainView.m @@ -23,16 +23,12 @@ - (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]; - [self.topBar mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.right.equalTo(self); - make.top.equalTo(self.mas_top).offset(6); - make.height.mas_equalTo(40); - }]; - // 键盘区域 self.keyboardView = [[KBKeyboardView alloc] init]; self.keyboardView.delegate = self; @@ -44,6 +40,14 @@ make.bottom.equalTo(self.mas_bottom).offset(-4); }]; + + [self.topBar mas_makeConstraints:^(MASConstraintMaker *make) { + make.left.right.equalTo(self); + make.top.equalTo(self.mas_top).offset(0); +// make.height.mas_equalTo(40); + make.bottom.equalTo(self.keyboardView.mas_top).offset(-6); + }]; + // 功能面板切换交由外部控制器处理;此处不直接创建/管理 } diff --git a/CustomKeyboard/View/KBKeyboardView.m b/CustomKeyboard/View/KBKeyboardView.m index 9ffe4f8..9582425 100644 --- a/CustomKeyboard/View/KBKeyboardView.m +++ b/CustomKeyboard/View/KBKeyboardView.m @@ -10,6 +10,24 @@ #import "KBSkinManager.h" #import "KBKeyPreviewView.h" +// UI 常量统一管理,方便后续调试样式 +static const CGFloat kKBRowVerticalSpacing = 8.0; +static const CGFloat kKBRowHorizontalInset = 6.0; +static const CGFloat kKBRowHeight = 40.0; + +static const NSTimeInterval kKBBackspaceLongPressMinDuration = 0.35; +static const NSTimeInterval kKBBackspaceRepeatInterval = 0.06; + +static const NSTimeInterval kKBPreviewShowDuration = 0.08; +static const NSTimeInterval kKBPreviewHideDuration = 0.06; + +static const CGFloat kKBSpecialKeySquareMultiplier = 1.2; +static const CGFloat kKBReturnWidthMultiplier = 2.4; +static const CGFloat kKBSpaceWidthMultiplier = 3.0; + +// 第二行字母行的左右占位比例(用于居中) +static const CGFloat kKBLettersRow2EdgeSpacerMultiplier = 0.5; + @interface KBKeyboardView () @property (nonatomic, strong) UIView *row1; @property (nonatomic, strong) UIView *row2; @@ -44,36 +62,39 @@ } } +#pragma mark - Base Layout + - (void)buildBase { [self addSubview:self.row1]; [self addSubview:self.row2]; [self addSubview:self.row3]; [self addSubview:self.row4]; - CGFloat vSpacing = 8; [self.row1 mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.mas_top).offset(8); + make.top.equalTo(self.mas_top).offset(kKBRowVerticalSpacing); make.left.right.equalTo(self); - make.height.mas_equalTo(40); + make.height.mas_equalTo(kKBRowHeight); }]; [self.row2 mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.row1.mas_bottom).offset(vSpacing); + make.top.equalTo(self.row1.mas_bottom).offset(kKBRowVerticalSpacing); make.left.right.equalTo(self); make.height.equalTo(self.row1); }]; [self.row3 mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.row2.mas_bottom).offset(vSpacing); + make.top.equalTo(self.row2.mas_bottom).offset(kKBRowVerticalSpacing); make.left.right.equalTo(self); make.height.equalTo(self.row1); }]; [self.row4 mas_makeConstraints:^(MASConstraintMaker *make) { - make.top.equalTo(self.row3.mas_bottom).offset(vSpacing); + make.top.equalTo(self.row3.mas_bottom).offset(kKBRowVerticalSpacing); make.left.right.equalTo(self); make.height.equalTo(self.row1); make.bottom.equalTo(self.mas_bottom).offset(-6); }]; } +#pragma mark - Public + - (void)reloadKeys { // 移除旧按钮 for (UIView *row in @[self.row1, self.row2, self.row3, self.row4]) { @@ -81,148 +102,49 @@ } self.keysForRows = [self buildKeysForCurrentLayout]; + if (self.keysForRows.count < 4) return; + [self buildRow:self.row1 withKeys:self.keysForRows[0]]; + // 第二行:字母布局时通过左右等宽占位让整行居中 - CGFloat row2Spacer = (self.layoutStyle == KBKeyboardLayoutStyleLetters) ? 0.5 : 0.0; + CGFloat row2Spacer = (self.layoutStyle == KBKeyboardLayoutStyleLetters) + ? kKBLettersRow2EdgeSpacerMultiplier : 0.0; [self buildRow:self.row2 withKeys:self.keysForRows[1] edgeSpacerMultiplier:row2Spacer]; + [self buildRow:self.row3 withKeys:self.keysForRows[2]]; [self buildRow:self.row4 withKeys:self.keysForRows[3]]; } +#pragma mark - Key Model Construction + +// 创建当前布局下各行的 KBKey 列表 - (NSArray *> *)buildKeysForCurrentLayout { if (self.layoutStyle == KBKeyboardLayoutStyleNumbers) { - // 数字/符号布局:3 行主键 + 底部控制行 - NSArray *r1 = nil; - NSArray *r2 = nil; - NSArray *r3 = nil; - - if (!self.symbolsMoreOn) { - // 数字第一页(123) - r1 = @[ [KBKey keyWithIdentifier:@"digit_1" title:@"1" output:@"1" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"digit_2" title:@"2" output:@"2" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"digit_3" title:@"3" output:@"3" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"digit_4" title:@"4" output:@"4" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"digit_5" title:@"5" output:@"5" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"digit_6" title:@"6" output:@"6" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"digit_7" title:@"7" output:@"7" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"digit_8" title:@"8" output:@"8" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"digit_9" title:@"9" output:@"9" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"digit_0" title:@"0" output:@"0" type:KBKeyTypeCharacter] ]; - r2 = @[ [KBKey keyWithIdentifier:@"sym_minus" title:@"-" output:@"-" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_slash" title:@"/" output:@"/" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_colon" title:@":" output:@":" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_semicolon" title:@";" output:@";" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_paren_l" title:@"(" output:@"(" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_paren_r" title:@")" output:@")" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_dollar" title:@"$" output:@"$" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_amp" title:@"&" output:@"&" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_at" title:@"@" output:@"@" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_quote_double" title:@"\"" output:@"\"" type:KBKeyTypeCharacter] ]; - // 第三行:左下角是“#+=”切换键,右下角是退格键 - KBKey *toggle = [KBKey keyWithIdentifier:@"symbols_toggle_more" - title:@"#+=" - output:@"" - type:KBKeyTypeSymbolsToggle]; - KBKey *comma = [KBKey keyWithIdentifier:@"sym_comma" title:@"," output:@"," type:KBKeyTypeCharacter]; - KBKey *dot = [KBKey keyWithIdentifier:@"sym_dot" title:@"." output:@"." type:KBKeyTypeCharacter]; - KBKey *q = [KBKey keyWithIdentifier:@"sym_question" title:@"?" output:@"?" type:KBKeyTypeCharacter]; - KBKey *ex = [KBKey keyWithIdentifier:@"sym_exclam" title:@"!" output:@"!" type:KBKeyTypeCharacter]; - KBKey *quote = [KBKey keyWithIdentifier:@"sym_quote_single" title:@"'" output:@"'" type:KBKeyTypeCharacter]; - KBKey *back = [KBKey keyWithIdentifier:@"backspace" - title:@"⌫" - output:@"" - type:KBKeyTypeBackspace]; - r3 = @[ toggle, comma, dot, q, ex, quote, back ]; - } else { - // 数字第二页(#+=):前两行替换为更多符号,左下角按钮文案改为“123” - r1 = @[ [KBKey keyWithIdentifier:@"sym_bracket_l" title:@"[" output:@"[" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_bracket_r" title:@"]" output:@"]" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_brace_l" title:@"{" output:@"{" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_brace_r" title:@"}" output:@"}" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_hash" title:@"#" output:@"#" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_percent" title:@"%" output:@"%" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_caret" title:@"^" output:@"^" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_asterisk" title:@"*" output:@"*" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_plus" title:@"+" output:@"+" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_equal" title:@"=" output:@"=" type:KBKeyTypeCharacter] ]; - r2 = @[ [KBKey keyWithIdentifier:@"sym_underscore" title:@"_" output:@"_" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_backslash" title:@"\\" output:@"\\" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_pipe" title:@"|" output:@"|" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_tilde" title:@"~" output:@"~" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_lt" title:@"<" output:@"<" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_gt" title:@">" output:@">" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_dollar" title:@"$" output:@"$" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_euro" title:@"€" output:@"€" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_pound" title:@"£" output:@"£" type:KBKeyTypeCharacter], - [KBKey keyWithIdentifier:@"sym_bullet" title:@"•" output:@"•" type:KBKeyTypeCharacter] ]; - KBKey *toggle = [KBKey keyWithIdentifier:@"symbols_toggle_123" - title:@"123" - output:@"" - type:KBKeyTypeSymbolsToggle]; - KBKey *comma = [KBKey keyWithIdentifier:@"sym_comma" title:@"," output:@"," type:KBKeyTypeCharacter]; - KBKey *dot = [KBKey keyWithIdentifier:@"sym_dot" title:@"." output:@"." type:KBKeyTypeCharacter]; - KBKey *q = [KBKey keyWithIdentifier:@"sym_question" title:@"?" output:@"?" type:KBKeyTypeCharacter]; - KBKey *ex = [KBKey keyWithIdentifier:@"sym_exclam" title:@"!" output:@"!" type:KBKeyTypeCharacter]; - KBKey *quote = [KBKey keyWithIdentifier:@"sym_quote_single" title:@"'" output:@"'" type:KBKeyTypeCharacter]; - KBKey *back = [KBKey keyWithIdentifier:@"backspace" - title:@"⌫" - output:@"" - type:KBKeyTypeBackspace]; - r3 = @[ toggle, comma, dot, q, ex, quote, back ]; - } - - KBKey *modeABC = [KBKey keyWithIdentifier:@"mode_abc" - title:@"abc" - output:@"" - type:KBKeyTypeModeChange]; - KBKey *customAI = [KBKey keyWithIdentifier:@"ai" - title:@"AI" - output:@"" - type:KBKeyTypeCustom]; - KBKey *space = [KBKey keyWithIdentifier:@"space" - title:@"space" - output:@" " - type:KBKeyTypeSpace]; - KBKey *ret = [KBKey keyWithIdentifier:@"return" - title:KBLocalized(@"Send") - output:@"\n" - type:KBKeyTypeReturn]; - - NSArray *r4 = @[ modeABC, customAI, space, ret ]; - - return @[r1, r2, r3, r4]; + return [self buildKeysForNumbersLayout]; + } else { + return [self buildKeysForLettersLayout]; } +} +#pragma mark - Letters Layout + +- (NSArray *> *)buildKeysForLettersLayout { // 字母布局(QWERTY) - NSArray *r1 = @[ @"Q", @"W", @"E", @"R", @"T", @"Y", @"U", @"I", @"O", @"P" ]; - NSArray *r2 = @[ @"A", @"S", @"D", @"F", @"G", @"H", @"J", @"K", @"L" ]; - NSArray *r3chars = @[ @"Z", @"X", @"C", @"V", @"B", @"N", @"M" ]; + NSArray *r1Letters = @[ @"q", @"w", @"e", @"r", @"t", @"y", @"u", @"i", @"o", @"p" ]; + NSArray *r2Letters = @[ @"a", @"s", @"d", @"f", @"g", @"h", @"j", @"k", @"l" ]; + NSArray *r3Letters = @[ @"z", @"x", @"c", @"v", @"b", @"n", @"m" ]; - NSMutableArray *row1 = [NSMutableArray arrayWithCapacity:r1.count]; - // 字母键标题与输出同时随 Shift 切换大小写,界面与输入保持一致 - for (NSString *s in r1) { - NSString *shown = self.shiftOn ? s : s.lowercaseString; - NSString *identifier = [NSString stringWithFormat:@"letter_%@", s.lowercaseString]; - KBKey *k = [KBKey keyWithIdentifier:identifier - title:shown - output:shown - type:KBKeyTypeCharacter]; - k.caseVariant = self.shiftOn ? KBKeyCaseVariantUpper : KBKeyCaseVariantLower; - [row1 addObject:k]; + NSMutableArray *row1 = [NSMutableArray arrayWithCapacity:r1Letters.count]; + for (NSString *s in r1Letters) { + [row1 addObject:[self kb_letterKeyWithChar:s]]; } - NSMutableArray *row2 = [NSMutableArray arrayWithCapacity:r2.count]; - for (NSString *s in r2) { - NSString *shown = self.shiftOn ? s : s.lowercaseString; - NSString *identifier = [NSString stringWithFormat:@"letter_%@", s.lowercaseString]; - KBKey *k = [KBKey keyWithIdentifier:identifier - title:shown - output:shown - type:KBKeyTypeCharacter]; - k.caseVariant = self.shiftOn ? KBKeyCaseVariantUpper : KBKeyCaseVariantLower; - [row2 addObject:k]; + NSMutableArray *row2 = [NSMutableArray arrayWithCapacity:r2Letters.count]; + for (NSString *s in r2Letters) { + [row2 addObject:[self kb_letterKeyWithChar:s]]; } + // 第三行:Shift + Z...M + Backspace NSMutableArray *row3 = [NSMutableArray array]; KBKey *shift = [KBKey keyWithIdentifier:@"shift" title:@"⇧" @@ -233,22 +155,126 @@ // - shift.caseVariant = Upper 时,使用 "shift_upper" 对应的短名。 shift.caseVariant = self.shiftOn ? KBKeyCaseVariantUpper : KBKeyCaseVariantLower; [row3 addObject:shift]; - for (NSString *s in r3chars) { - NSString *shown = self.shiftOn ? s : s.lowercaseString; - NSString *identifier = [NSString stringWithFormat:@"letter_%@", s.lowercaseString]; - KBKey *k = [KBKey keyWithIdentifier:identifier - title:shown - output:shown - type:KBKeyTypeCharacter]; - k.caseVariant = self.shiftOn ? KBKeyCaseVariantUpper : KBKeyCaseVariantLower; - [row3 addObject:k]; + + for (NSString *s in r3Letters) { + [row3 addObject:[self kb_letterKeyWithChar:s]]; } + KBKey *backspace = [KBKey keyWithIdentifier:@"backspace" title:@"⌫" output:@"" type:KBKeyTypeBackspace]; [row3 addObject:backspace]; + NSArray *row4 = [self kb_bottomControlRowKeysForLettersLayout]; + + return @[row1.copy, row2.copy, row3.copy, row4]; +} + +#pragma mark - Numbers / Symbols Layout + +- (NSArray *> *)buildKeysForNumbersLayout { + // 数字/符号布局:3 行主键 + 底部控制行 + NSArray *r1 = nil; + NSArray *r2 = nil; + NSArray *r3 = nil; + + if (!self.symbolsMoreOn) { + // 数字第一页(123) + r1 = @[ [KBKey keyWithIdentifier:@"digit_1" title:@"1" output:@"1" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"digit_2" title:@"2" output:@"2" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"digit_3" title:@"3" output:@"3" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"digit_4" title:@"4" output:@"4" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"digit_5" title:@"5" output:@"5" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"digit_6" title:@"6" output:@"6" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"digit_7" title:@"7" output:@"7" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"digit_8" title:@"8" output:@"8" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"digit_9" title:@"9" output:@"9" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"digit_0" title:@"0" output:@"0" type:KBKeyTypeCharacter] ]; + r2 = @[ [KBKey keyWithIdentifier:@"sym_minus" title:@"-" output:@"-" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_slash" title:@"/" output:@"/" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_colon" title:@":" output:@":" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_semicolon" title:@";" output:@";" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_paren_l" title:@"(" output:@"(" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_paren_r" title:@")" output:@")" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_dollar" title:@"$" output:@"$" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_amp" title:@"&" output:@"&" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_at" title:@"@" output:@"@" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_quote_double" title:@"\"" output:@"\"" type:KBKeyTypeCharacter] ]; + + r3 = [self kb_symbolsCommonThirdRowWithToggleIsMore:NO]; + } else { + // 数字第二页(#+=):前两行替换为更多符号,左下角按钮文案改为“123” + r1 = @[ [KBKey keyWithIdentifier:@"sym_bracket_l" title:@"[" output:@"[" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_bracket_r" title:@"]" output:@"]" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_brace_l" title:@"{" output:@"{" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_brace_r" title:@"}" output:@"}" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_hash" title:@"#" output:@"#" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_percent" title:@"%" output:@"%" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_caret" title:@"^" output:@"^" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_asterisk" title:@"*" output:@"*" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_plus" title:@"+" output:@"+" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_equal" title:@"=" output:@"=" type:KBKeyTypeCharacter] ]; + r2 = @[ [KBKey keyWithIdentifier:@"sym_underscore" title:@"_" output:@"_" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_backslash" title:@"\\" output:@"\\" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_pipe" title:@"|" output:@"|" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_tilde" title:@"~" output:@"~" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_lt" title:@"<" output:@"<" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_gt" title:@">" output:@">" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_dollar" title:@"$" output:@"$" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_euro" title:@"€" output:@"€" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_pound" title:@"£" output:@"£" type:KBKeyTypeCharacter], + [KBKey keyWithIdentifier:@"sym_bullet" title:@"•" output:@"•" type:KBKeyTypeCharacter] ]; + + r3 = [self kb_symbolsCommonThirdRowWithToggleIsMore:YES]; + } + + NSArray *r4 = [self kb_bottomControlRowKeysForNumbersLayout]; + return @[r1, r2, r3, r4]; +} + +#pragma mark - Key Factories + +// 字母键工厂:根据 shiftOn 决定显示与输出大小写 +- (KBKey *)kb_letterKeyWithChar:(NSString *)charString { + NSParameterAssert(charString.length == 1); + NSString *lower = charString.lowercaseString; + NSString *upper = charString.uppercaseString; + + NSString *shown = self.shiftOn ? upper : lower; + NSString *identifier = [NSString stringWithFormat:@"letter_%@", lower]; + + KBKey *k = [KBKey keyWithIdentifier:identifier + title:shown + output:shown + type:KBKeyTypeCharacter]; + k.caseVariant = self.shiftOn ? KBKeyCaseVariantUpper : KBKeyCaseVariantLower; + return k; +} + +// 数字布局第三行公共部分(左下角是 123 或 #+=) +- (NSArray *)kb_symbolsCommonThirdRowWithToggleIsMore:(BOOL)isMorePage { + NSString *identifier = isMorePage ? @"symbols_toggle_123" : @"symbols_toggle_more"; + NSString *title = isMorePage ? @"123" : @"#+="; + + KBKey *toggle = [KBKey keyWithIdentifier:identifier + title:title + output:@"" + type:KBKeyTypeSymbolsToggle]; + KBKey *comma = [KBKey keyWithIdentifier:@"sym_comma" title:@"," output:@"," type:KBKeyTypeCharacter]; + KBKey *dot = [KBKey keyWithIdentifier:@"sym_dot" title:@"." output:@"." type:KBKeyTypeCharacter]; + KBKey *q = [KBKey keyWithIdentifier:@"sym_question" title:@"?" output:@"?" type:KBKeyTypeCharacter]; + KBKey *ex = [KBKey keyWithIdentifier:@"sym_exclam" title:@"!" output:@"!" type:KBKeyTypeCharacter]; + KBKey *quote = [KBKey keyWithIdentifier:@"sym_quote_single" title:@"'" output:@"'" type:KBKeyTypeCharacter]; + KBKey *back = [KBKey keyWithIdentifier:@"backspace" + title:@"⌫" + output:@"" + type:KBKeyTypeBackspace]; + return @[ toggle, comma, dot, q, ex, quote, back ]; +} + +// 底部控制行(字母布局) +- (NSArray *)kb_bottomControlRowKeysForLettersLayout { KBKey *mode123 = [KBKey keyWithIdentifier:@"mode_123" title:@"123" output:@"" @@ -265,26 +291,49 @@ title:KBLocalized(@"Send") output:@"\n" type:KBKeyTypeReturn]; - - NSArray *row4 = @[ mode123, customAI, space, ret ]; - - return @[row1.copy, row2.copy, row3.copy, row4]; + return @[ mode123, customAI, space, ret ]; } +// 底部控制行(数字布局) +- (NSArray *)kb_bottomControlRowKeysForNumbersLayout { + KBKey *modeABC = [KBKey keyWithIdentifier:@"mode_abc" + title:@"abc" + output:@"" + type:KBKeyTypeModeChange]; + KBKey *customAI = [KBKey keyWithIdentifier:@"ai" + title:@"AI" + output:@"" + type:KBKeyTypeCustom]; + KBKey *space = [KBKey keyWithIdentifier:@"space" + title:@"space" + output:@" " + type:KBKeyTypeSpace]; + KBKey *ret = [KBKey keyWithIdentifier:@"return" + title:KBLocalized(@"Send") + output:@"\n" + type:KBKeyTypeReturn]; + return @[ modeABC, customAI, space, ret ]; +} + +#pragma mark - Row Building + - (void)buildRow:(UIView *)row withKeys:(NSArray *)keys { [self buildRow:row withKeys:keys edgeSpacerMultiplier:0.0]; } -- (void)buildRow:(UIView *)row withKeys:(NSArray *)keys edgeSpacerMultiplier:(CGFloat)edgeSpacerMultiplier { +- (void)buildRow:(UIView *)row + withKeys:(NSArray *)keys +edgeSpacerMultiplier:(CGFloat)edgeSpacerMultiplier { + // 第 4 行(底部控制行)使用单独的布局规则: // 123/ABC、AI、Send 给定尺寸,Space 自动吃掉剩余宽度。 BOOL isBottomControlRow = [self kb_isBottomControlRowWithKeys:keys]; - CGFloat hInset = 6; // 行左右内边距 CGFloat spacing = 0; // 键与键之间的间距 UIView *previous = nil; UIView *leftSpacer = nil; UIView *rightSpacer = nil; + if (edgeSpacerMultiplier > 0.0) { leftSpacer = [UIView new]; rightSpacer = [UIView new]; @@ -293,16 +342,17 @@ [row addSubview:leftSpacer]; [row addSubview:rightSpacer]; [leftSpacer mas_makeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(row.mas_left).offset(hInset); + make.left.equalTo(row.mas_left).offset(kKBRowHorizontalInset); make.centerY.equalTo(row); make.height.mas_equalTo(1); }]; [rightSpacer mas_makeConstraints:^(MASConstraintMaker *make) { - make.right.equalTo(row.mas_right).offset(-hInset); + make.right.equalTo(row.mas_right).offset(-kKBRowHorizontalInset); make.centerY.equalTo(row); make.height.mas_equalTo(1); }]; } + for (NSInteger i = 0; i < keys.count; i++) { KBKey *key = keys[i]; KBKeyButton *btn = [[KBKeyButton alloc] init]; @@ -313,12 +363,12 @@ [btn addTarget:self action:@selector(onKeyTapped:) forControlEvents:UIControlEventTouchUpInside]; [row addSubview:btn]; - // ⌫ 长按:开始连续逐个删除(无需 NSTimer)。使用 UILongPressGestureRecognizer 识别长按, - // 在开始态触发递归的轻量调度,每次删除 1 个字符,直到松手或无内容。 + // ⌫ 长按:开始连续逐个删除(无需 NSTimer)。使用 UILongPressGestureRecognizer 识别长按 if (key.type == KBKeyTypeBackspace) { - UILongPressGestureRecognizer *lp = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(onBackspaceLongPress:)]; - // 稍短的判定时间,提升响应(默认约 0.5s)。 - lp.minimumPressDuration = 0.35; + UILongPressGestureRecognizer *lp = + [[UILongPressGestureRecognizer alloc] initWithTarget:self + action:@selector(onBackspaceLongPress:)]; + lp.minimumPressDuration = kKBBackspaceLongPressMinDuration; lp.cancelsTouchesInView = YES; // 被识别为长按时,取消普通点击 [btn addGestureRecognizer:lp]; } @@ -336,35 +386,38 @@ if (leftSpacer) { make.left.equalTo(leftSpacer.mas_right).offset(spacing); } else { - make.left.equalTo(row.mas_left).offset(hInset); + make.left.equalTo(row.mas_left).offset(kKBRowHorizontalInset); } } }]; - // 宽度规则:字符键等宽;特殊键按倍数放大 + // 字符键:等宽 if (key.type == KBKeyTypeCharacter) { - if (previous && previous != nil) { - if (((KBKeyButton *)previous).key.type == KBKeyTypeCharacter) { + if (previous && [previous isKindOfClass:[KBKeyButton class]]) { + KBKeyButton *prevBtn = (KBKeyButton *)previous; + if (prevBtn.key.type == KBKeyTypeCharacter) { [btn mas_makeConstraints:^(MASConstraintMaker *make) { make.width.equalTo(previous); }]; } } } else { - // special keys: give 1.5x of a character key by deferring constraint equalities after loop + // special keys: 宽度在第二遍统一设置 } previous = btn; } // 右侧使用内边距或右占位 - [previous mas_makeConstraints:^(MASConstraintMaker *make) { - if (rightSpacer) { - make.right.equalTo(rightSpacer.mas_left).offset(-spacing); - } else { - make.right.equalTo(row.mas_right).offset(-hInset); - } - }]; + if (previous) { + [previous mas_makeConstraints:^(MASConstraintMaker *make) { + if (rightSpacer) { + make.right.equalTo(rightSpacer.mas_left).offset(-spacing); + } else { + make.right.equalTo(row.mas_right).offset(-kKBRowHorizontalInset); + } + }]; + } // 底部控制行:在第一轮已完成左右约束的前提下,仅给 123/ABC、AI、Send 指定宽度, // Space 不加宽度约束,让其自动填充剩余空间。 @@ -376,19 +429,20 @@ // 第二遍:以首个字符键为基准,统一设置特殊键宽度倍数 KBKeyButton *firstChar = nil; BOOL hasCharacterInRow = NO; - for (KBKeyButton *b in row.subviews) { - if (![b isKindOfClass:[KBKeyButton class]]) continue; + for (UIView *v in row.subviews) { + if (![v isKindOfClass:[KBKeyButton class]]) continue; + KBKeyButton *b = (KBKeyButton *)v; if (b.key.type == KBKeyTypeCharacter) { firstChar = b; hasCharacterInRow = YES; break; } } - // 若该行没有字符键(例如底部控制行),则使用行内第一个按钮作为基准宽度 + // 若该行没有字符键(例如底部控制行之外的特殊行),则使用行内第一个按钮作为基准宽度 if (!firstChar) { - for (KBKeyButton *b in row.subviews) { - if ([b isKindOfClass:[KBKeyButton class]]) { - firstChar = b; + for (UIView *v in row.subviews) { + if ([v isKindOfClass:[KBKeyButton class]]) { + firstChar = (KBKeyButton *)v; break; } } @@ -401,41 +455,40 @@ firstChar.key.type == KBKeyTypeSymbolsToggle || firstChar.key.type == KBKeyTypeCustom)) { [firstChar mas_makeConstraints:^(MASConstraintMaker *make) { - make.width.equalTo(firstChar.mas_height); + make.width.equalTo(firstChar.mas_height).multipliedBy(kKBSpecialKeySquareMultiplier); }]; } - for (KBKeyButton *b in row.subviews) { - if (![b isKindOfClass:[KBKeyButton class]]) continue; - // 当本行没有字符键时,firstChar 可能是一个“特殊键”, + + for (UIView *v in row.subviews) { + if (![v isKindOfClass:[KBKeyButton class]]) continue; + KBKeyButton *b = (KBKeyButton *)v; + // 避免对基准按钮自身添加 self == self * k 的无效约束 if (b == firstChar) continue; if (b.key.type == KBKeyTypeCharacter) continue; - // 一类键强制宽高比 1:1: - // - 第三行:Shift、Backspace - // - 第四行:123/ABC(ModeChange)、#+=(SymbolsToggle)、AI(Custom) - // (真正的底部控制行在上面已单独处理,这里主要服务于第三行的 #+= 等) BOOL isBottomModeKey = (b.key.type == KBKeyTypeModeChange) || (b.key.type == KBKeyTypeSymbolsToggle) || (b.key.type == KBKeyTypeCustom); + // 一类键强制近似正方形(宽 ~ 高) if (b.key.type == KBKeyTypeShift || b.key.type == KBKeyTypeBackspace || isBottomModeKey) { [b mas_makeConstraints:^(MASConstraintMaker *make) { - make.width.equalTo(b.mas_height).multipliedBy(1.2); // 宽度 = 高度,做成正方形 + make.width.equalTo(b.mas_height).multipliedBy(kKBSpecialKeySquareMultiplier); }]; continue; } CGFloat multiplier = 1.5; - // Space:根据行宽可压缩,适当缩小宽度(原来是 4.0,略微调低到 3.0) + // Space:宽度更大 if (b.key.type == KBKeyTypeSpace) { - multiplier = 3.0; + multiplier = kKBSpaceWidthMultiplier; } // Send 按钮:宽度为基准键的 2.4 倍 else if (b.key.type == KBKeyTypeReturn) { - multiplier = 2.4; + multiplier = kKBReturnWidthMultiplier; } // 其它特殊键(如 Globe)保持适度放大 else if (b.key.type == KBKeyTypeGlobe) { @@ -446,6 +499,7 @@ make.width.equalTo(firstChar).multipliedBy(multiplier); }]; } + // 如果有左右占位,则把占位宽度设置为字符键宽度的一定倍数,以实现整体居中 if (leftSpacer && rightSpacer) { [leftSpacer mas_makeConstraints:^(MASConstraintMaker *make) { @@ -482,8 +536,8 @@ } // 为底部控制行设置宽度: -// - 123/ABC、AI:正方形(宽 = 行高) -// - Send:宽 = 模式键宽度的 2.4 倍 +// - 123/ABC、AI:正方形(宽 = 行高 * multiplier) +// - Send:宽 = 模式键宽度的 2 倍 // - Space:不加宽度约束,依靠左右约束自动填充剩余空间。 - (void)kb_applyBottomControlRowWidthInRow:(UIView *)row { KBKeyButton *modeBtn = nil; @@ -519,14 +573,14 @@ // 行高由外部约束为固定值(等于 row1 高度),这里用行高作为“正方形”的边长。 [modeBtn mas_makeConstraints:^(MASConstraintMaker *make) { - make.width.equalTo(row.mas_height).multipliedBy(1.2); + make.width.equalTo(row.mas_height).multipliedBy(kKBSpecialKeySquareMultiplier); }]; [aiBtn mas_makeConstraints:^(MASConstraintMaker *make) { - make.width.equalTo(row.mas_height).multipliedBy(1.2); + make.width.equalTo(row.mas_height).multipliedBy(kKBSpecialKeySquareMultiplier); }]; [retBtn mas_makeConstraints:^(MASConstraintMaker *make) { - // Send 按钮:宽度为模式键的 2.4 倍 - make.width.equalTo(modeBtn.mas_width).multipliedBy(2); + // Send 按钮:宽度为模式键的 2 倍 + make.width.equalTo(modeBtn.mas_width).multipliedBy(2.0); }]; // Space 不设置宽度;通过此前已建立的左右约束自动占满剩余宽度。 } @@ -571,12 +625,13 @@ CGFloat centerX = CGRectGetMidX(btnFrameInSelf); CGFloat centerY = CGRectGetMinY(btnFrameInSelf) - previewHeight * 0.6; - self.previewView.frame = CGRectMake(0, 0, 40, previewHeight); + // 修复:原来写死 40,这里用真正计算出的 previewWidth + self.previewView.frame = CGRectMake(0, 0, previewWidth, previewHeight); self.previewView.center = CGPointMake(centerX, centerY); self.previewView.alpha = 0.0; self.previewView.hidden = NO; - [UIView animateWithDuration:0.08 + [UIView animateWithDuration:kKBPreviewShowDuration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut animations:^{ @@ -587,7 +642,7 @@ - (void)hidePreview { if (!self.previewView || self.previewView.isHidden) return; - [UIView animateWithDuration:0.06 + [UIView animateWithDuration:kKBPreviewHideDuration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseIn animations:^{ @@ -627,7 +682,9 @@ [proxy deleteBackward]; // 每次仅删 1 个 __weak typeof(self) weakSelf = self; - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.06 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, + (int64_t)(kKBBackspaceRepeatInterval * NSEC_PER_SEC)), + dispatch_get_main_queue(), ^{ __strong typeof(weakSelf) selfStrong = weakSelf; [selfStrong kb_backspaceStep]; }); diff --git a/CustomKeyboard/View/KBToolBar.m b/CustomKeyboard/View/KBToolBar.m index 9158f2e..9c0e84c 100644 --- a/CustomKeyboard/View/KBToolBar.m +++ b/CustomKeyboard/View/KBToolBar.m @@ -11,7 +11,7 @@ @interface KBToolBar () @property (nonatomic, strong) UIView *leftContainer; @property (nonatomic, strong) NSArray *leftButtonsInternal; -@property (nonatomic, strong) UIButton *settingsButtonInternal; +//@property (nonatomic, strong) UIButton *settingsButtonInternal; @property (nonatomic, strong) UIButton *globeButtonInternal; // 可选:系统“切换输入法”键 @end @@ -20,7 +20,7 @@ - (instancetype)initWithFrame:(CGRect)frame{ if (self = [super initWithFrame:frame]) { self.backgroundColor = [UIColor clearColor]; - _leftButtonTitles = @[@"Item1", @"Item2", @"Item3", @"Item4"]; // 默认标题 + _leftButtonTitles = @[KBLocalized(@"Recharge Now")]; // 默认标题 [self setupUI]; } return self; @@ -33,9 +33,9 @@ return self.leftButtonsInternal; } -- (UIButton *)settingsButton { - return self.settingsButtonInternal; -} +//- (UIButton *)settingsButton { +// return self.settingsButtonInternal; +//} - (void)setLeftButtonTitles:(NSArray *)leftButtonTitles { _leftButtonTitles = [leftButtonTitles copy]; @@ -51,15 +51,15 @@ - (void)setupUI { [self addSubview:self.leftContainer]; - [self addSubview:self.settingsButtonInternal]; +// [self addSubview:self.settingsButtonInternal]; [self addSubview:self.globeButtonInternal]; // 右侧设置按钮 - [self.settingsButtonInternal mas_makeConstraints:^(MASConstraintMaker *make) { - make.right.equalTo(self.mas_right).offset(-12); - make.centerY.equalTo(self.mas_centerY); - make.width.height.mas_equalTo(32); - }]; +// [self.settingsButtonInternal mas_makeConstraints:^(MASConstraintMaker *make) { +// make.right.equalTo(self.mas_right).offset(-12); +// make.centerY.equalTo(self.mas_centerY); +// make.width.height.mas_equalTo(32); +// }]; // 左侧地球键(按需显示) [self.globeButtonInternal mas_makeConstraints:^(MASConstraintMaker *make) { @@ -71,33 +71,41 @@ // 左侧容器占用剩余空间 [self.leftContainer mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.globeButtonInternal.mas_right).offset(8); - make.right.equalTo(self.settingsButtonInternal.mas_left).offset(-12); + make.right.equalTo(self).offset(-12); make.centerY.equalTo(self.mas_centerY); make.height.mas_equalTo(32); }]; - // 在左侧容器中创建 4 个等宽按钮 - NSMutableArray *buttons = [NSMutableArray arrayWithCapacity:4]; + // 在左侧容器中创建按钮(数量 = 标题数量) + NSMutableArray *buttons = [NSMutableArray arrayWithCapacity:_leftButtonTitles.count]; UIView *previous = nil; - for (NSInteger i = 0; i < 4; i++) { + for (NSInteger i = 0; i < _leftButtonTitles.count; i++) { UIButton *btn = [self buildActionButtonAtIndex:i]; [self.leftContainer addSubview:btn]; [buttons addObject:btn]; + [btn mas_makeConstraints:^(MASConstraintMaker *make) { + make.top.bottom.equalTo(self.leftContainer); + if (previous) { make.left.equalTo(previous.mas_right).offset(8); - make.width.equalTo(previous); } else { make.left.equalTo(self.leftContainer.mas_left); } - make.top.bottom.equalTo(self.leftContainer); + // 不再设置宽度约束,交给 intrinsicContentSize }]; + previous = btn; } - // 最后一个按钮贴右侧 - [previous mas_makeConstraints:^(MASConstraintMaker *make) { - make.right.equalTo(self.leftContainer.mas_right); - }]; + + // 可选:最后一个不要一定贴右边,避免被拉伸 + // 如果你希望它最多到右边,可以这样: + if (previous) { + [previous mas_makeConstraints:^(MASConstraintMaker *make) { + make.right.lessThanOrEqualTo(self.leftContainer.mas_right); + }]; + } + self.leftButtonsInternal = buttons.copy; // 初始刷新地球键的可见性与事件绑定 @@ -110,9 +118,16 @@ btn.layer.masksToBounds = YES; btn.backgroundColor = [UIColor colorWithWhite:1 alpha:0.9]; btn.titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium]; - NSString *title = (idx < self.leftButtonTitles.count) ? self.leftButtonTitles[idx] : [NSString stringWithFormat:@"Item%ld", (long)(idx+1)]; + + NSString *title = (idx < self.leftButtonTitles.count) ? self.leftButtonTitles[idx] : @""; [btn setTitle:title forState:UIControlStateNormal]; [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; + + // 关键:左右各 10,按钮宽度 = 文本宽度 + 20 + btn.contentEdgeInsets = UIEdgeInsetsMake(0, 10, 0, 10); + [btn setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; + [btn setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal]; + btn.tag = idx; [btn addTarget:self action:@selector(onLeftAction:) forControlEvents:UIControlEventTouchUpInside]; return btn; @@ -142,18 +157,18 @@ return _leftContainer; } -- (UIButton *)settingsButtonInternal { - if (!_settingsButtonInternal) { - _settingsButtonInternal = [UIButton buttonWithType:UIButtonTypeSystem]; - _settingsButtonInternal.layer.cornerRadius = 16; - _settingsButtonInternal.layer.masksToBounds = YES; - _settingsButtonInternal.backgroundColor = [UIColor colorWithWhite:1 alpha:0.9]; - [_settingsButtonInternal setTitle:@"⚙︎" forState:UIControlStateNormal]; // 简单的齿轮符号 - [_settingsButtonInternal setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; - [_settingsButtonInternal addTarget:self action:@selector(onSettings) forControlEvents:UIControlEventTouchUpInside]; - } - return _settingsButtonInternal; -} +//- (UIButton *)settingsButtonInternal { +// if (!_settingsButtonInternal) { +// _settingsButtonInternal = [UIButton buttonWithType:UIButtonTypeSystem]; +// _settingsButtonInternal.layer.cornerRadius = 16; +// _settingsButtonInternal.layer.masksToBounds = YES; +// _settingsButtonInternal.backgroundColor = [UIColor colorWithWhite:1 alpha:0.9]; +// [_settingsButtonInternal setTitle:@"⚙︎" forState:UIControlStateNormal]; // 简单的齿轮符号 +// [_settingsButtonInternal setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; +// [_settingsButtonInternal addTarget:self action:@selector(onSettings) forControlEvents:UIControlEventTouchUpInside]; +// } +// return _settingsButtonInternal; +//} - (UIButton *)globeButtonInternal { if (!_globeButtonInternal) { @@ -186,7 +201,7 @@ } else { make.left.equalTo(self.mas_left).offset(12); } - make.right.equalTo(self.settingsButtonInternal.mas_left).offset(-12); + make.right.equalTo(self).offset(-12); make.centerY.equalTo(self.mas_centerY); make.height.mas_equalTo(32); }]; diff --git a/keyBoard/Class/Pay/VC/KBJfPay.m b/keyBoard/Class/Pay/VC/KBJfPay.m index e2edf54..3c960fd 100644 --- a/keyBoard/Class/Pay/VC/KBJfPay.m +++ b/keyBoard/Class/Pay/VC/KBJfPay.m @@ -297,7 +297,7 @@ static NSString * const kKBJfPayCellId = @"kKBJfPayCellId"; - (UILabel *)rechargeLabel { if (!_rechargeLabel) { _rechargeLabel = [UILabel new]; - _rechargeLabel.text = @"Recharge Now"; + _rechargeLabel.text = KBLocalized(@"Recharge Now"); _rechargeLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; _rechargeLabel.textColor = [UIColor colorWithHex:KBBlackValue]; }