3
This commit is contained in:
@@ -20,13 +20,29 @@ typedef NS_ENUM(NSInteger, KBKeyType) {
|
||||
KBKeyTypeSymbolsToggle // 数字面板内的“#+=/123”切换
|
||||
};
|
||||
|
||||
/// 字母键的大小写变体标记(非字母键使用 KBKeyCaseVariantNone)
|
||||
typedef NS_ENUM(NSInteger, KBKeyCaseVariant) {
|
||||
KBKeyCaseVariantNone = 0,
|
||||
KBKeyCaseVariantLower = 1,
|
||||
KBKeyCaseVariantUpper = 2,
|
||||
};
|
||||
|
||||
@interface KBKey : NSObject
|
||||
|
||||
@property (nonatomic, assign) KBKeyType type;
|
||||
@property (nonatomic, copy) NSString *title; // 显示标题
|
||||
@property (nonatomic, copy) NSString *output; // 字符键插入的文本
|
||||
/// 逻辑按键标识,用于皮肤映射(如 @"letter_q" @"space" @"backspace")
|
||||
@property (nonatomic, copy, nullable) NSString *identifier;
|
||||
/// 字母键的大小写变体(便于皮肤为大小写准备不同图)
|
||||
@property (nonatomic, assign) KBKeyCaseVariant caseVariant;
|
||||
|
||||
+ (instancetype)keyWithTitle:(NSString *)title output:(NSString *)output;
|
||||
+ (instancetype)keyWithTitle:(NSString *)title type:(KBKeyType)type;
|
||||
/// 通用构造方法:用于指定 identifier,便于皮肤做精细控制
|
||||
+ (instancetype)keyWithIdentifier:(nullable NSString *)identifier
|
||||
title:(NSString *)title
|
||||
output:(NSString *)output
|
||||
type:(KBKeyType)type;
|
||||
|
||||
@end
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
k.type = KBKeyTypeCharacter;
|
||||
k.title = title ?: @"";
|
||||
k.output = output ?: title ?: @"";
|
||||
k.caseVariant = KBKeyCaseVariantNone;
|
||||
return k;
|
||||
}
|
||||
|
||||
@@ -20,8 +21,21 @@
|
||||
k.type = type;
|
||||
k.title = title ?: @"";
|
||||
k.output = @"";
|
||||
k.caseVariant = KBKeyCaseVariantNone;
|
||||
return k;
|
||||
}
|
||||
|
||||
+ (instancetype)keyWithIdentifier:(NSString *)identifier
|
||||
title:(NSString *)title
|
||||
output:(NSString *)output
|
||||
type:(KBKeyType)type {
|
||||
KBKey *k = [[KBKey alloc] init];
|
||||
k.type = type;
|
||||
k.identifier = identifier;
|
||||
k.title = title ?: @"";
|
||||
k.output = output ?: @"";
|
||||
k.caseVariant = KBKeyCaseVariantNone;
|
||||
return k;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@@ -17,4 +17,7 @@
|
||||
/// 根据选中/高亮等状态刷新外观
|
||||
- (void)refreshStateAppearance;
|
||||
|
||||
/// 根据当前皮肤与按键标识,应用图标和文字显隐等细节
|
||||
- (void)applyThemeForCurrentKey;
|
||||
|
||||
@end
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
#import "KBKey.h"
|
||||
#import "KBSkinManager.h"
|
||||
|
||||
@interface KBKeyButton ()
|
||||
@property (nonatomic, strong) UIImageView *iconView;
|
||||
@end
|
||||
|
||||
@implementation KBKeyButton
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
@@ -29,6 +33,34 @@
|
||||
self.layer.shadowOffset = CGSizeMake(0, 1);
|
||||
self.layer.shadowRadius = 1.5;
|
||||
[self refreshStateAppearance];
|
||||
|
||||
// 懒创建图标视图,用于后续皮肤按键小图标展示
|
||||
if (!self.iconView) {
|
||||
UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectZero];
|
||||
// 作为按键的整块皮肤背景,铺满整个按钮区域
|
||||
iv.contentMode = UIViewContentModeScaleAspectFill;
|
||||
iv.clipsToBounds = YES;
|
||||
iv.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self addSubview:iv];
|
||||
// 让皮肤图片撑满整个按钮
|
||||
[NSLayoutConstraint activateConstraints:@[
|
||||
[iv.topAnchor constraintEqualToAnchor:self.topAnchor],
|
||||
[iv.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
|
||||
[iv.leadingAnchor constraintEqualToAnchor:self.leadingAnchor],
|
||||
[iv.trailingAnchor constraintEqualToAnchor:self.trailingAnchor],
|
||||
]];
|
||||
self.iconView = iv;
|
||||
|
||||
// 文字保持居中;若需要显示文字,则覆盖在皮肤图片之上
|
||||
self.titleEdgeInsets = UIEdgeInsetsZero;
|
||||
[self bringSubviewToFront:self.titleLabel];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setKey:(KBKey *)key {
|
||||
_key = key;
|
||||
// 每次切换按键模型时,根据皮肤刷新一次图标和文字显隐
|
||||
[self applyThemeForCurrentKey];
|
||||
}
|
||||
|
||||
- (void)setHighlighted:(BOOL)highlighted {
|
||||
@@ -56,4 +88,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (void)applyThemeForCurrentKey {
|
||||
// 依据皮肤决定是否显示文字
|
||||
NSString *identifier = self.key.identifier;
|
||||
BOOL hideText = [[KBSkinManager shared] shouldHideKeyTextForIdentifier:identifier];
|
||||
self.titleLabel.hidden = hideText;
|
||||
|
||||
// 根据皮肤映射加载图标(若有),支持大小写变体:
|
||||
// - identifier: 逻辑按键标识(如 letter_q)
|
||||
// - caseVariant: 0/1/2 => 无变体/小写/大写
|
||||
NSInteger variant = (NSInteger)self.key.caseVariant;
|
||||
UIImage *iconImg = [[KBSkinManager shared] iconImageForKeyIdentifier:identifier caseVariant:variant];
|
||||
self.iconView.image = iconImg;
|
||||
self.iconView.hidden = (iconImg == nil);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -96,16 +96,41 @@
|
||||
|
||||
if (!self.symbolsMoreOn) {
|
||||
// 数字第一页(123)
|
||||
r1 = @[ [KBKey keyWithTitle:@"1" output:@"1"], [KBKey keyWithTitle:@"2" output:@"2"], [KBKey keyWithTitle:@"3" output:@"3"],
|
||||
[KBKey keyWithTitle:@"4" output:@"4"], [KBKey keyWithTitle:@"5" output:@"5"], [KBKey keyWithTitle:@"6" output:@"6"],
|
||||
[KBKey keyWithTitle:@"7" output:@"7"], [KBKey keyWithTitle:@"8" output:@"8"], [KBKey keyWithTitle:@"9" output:@"9"], [KBKey keyWithTitle:@"0" output:@"0"] ];
|
||||
r2 = @[ [KBKey keyWithTitle:@"-" output:@"-"], [KBKey keyWithTitle:@"/" output:@"/"], [KBKey keyWithTitle:@":" output:@":"],
|
||||
[KBKey keyWithTitle:@";" output:@";"], [KBKey keyWithTitle:@"(" output:@"("], [KBKey keyWithTitle:@")" output:@")"],
|
||||
[KBKey keyWithTitle:@"$" output:@"$"], [KBKey keyWithTitle:@"&" output:@"&"], [KBKey keyWithTitle:@"@" output:@"@"], [KBKey keyWithTitle:@"\"" output:@"\""] ];
|
||||
r3 = @[ [KBKey keyWithTitle:@"#+=" type:KBKeyTypeSymbolsToggle],
|
||||
[KBKey keyWithTitle:@"," output:@","], [KBKey keyWithTitle:@"." output:@"."], [KBKey keyWithTitle:@"?" output:@"?"],
|
||||
[KBKey keyWithTitle:@"!" output:@"!"], [KBKey keyWithTitle:@"'" output:@"'"],
|
||||
[KBKey keyWithTitle:@"⌫" type:KBKeyTypeBackspace] ];
|
||||
r1 = @[ [KBKey keyWithTitle:@"1" output:@"1"],
|
||||
[KBKey keyWithTitle:@"2" output:@"2"],
|
||||
[KBKey keyWithTitle:@"3" output:@"3"],
|
||||
[KBKey keyWithTitle:@"4" output:@"4"],
|
||||
[KBKey keyWithTitle:@"5" output:@"5"],
|
||||
[KBKey keyWithTitle:@"6" output:@"6"],
|
||||
[KBKey keyWithTitle:@"7" output:@"7"],
|
||||
[KBKey keyWithTitle:@"8" output:@"8"],
|
||||
[KBKey keyWithTitle:@"9" output:@"9"],
|
||||
[KBKey keyWithTitle:@"0" output:@"0"] ];
|
||||
r2 = @[ [KBKey keyWithTitle:@"-" output:@"-"],
|
||||
[KBKey keyWithTitle:@"/" output:@"/"],
|
||||
[KBKey keyWithTitle:@":" output:@":"],
|
||||
[KBKey keyWithTitle:@";" output:@";"],
|
||||
[KBKey keyWithTitle:@"(" output:@"("],
|
||||
[KBKey keyWithTitle:@")" output:@")"],
|
||||
[KBKey keyWithTitle:@"$" output:@"$"],
|
||||
[KBKey keyWithTitle:@"&" output:@"&"],
|
||||
[KBKey keyWithTitle:@"@" output:@"@"],
|
||||
[KBKey keyWithTitle:@"\"" output:@"\""] ];
|
||||
// 第三行:左下角是“#+=”切换键,右下角是退格键
|
||||
KBKey *toggle = [KBKey keyWithIdentifier:@"symbols_toggle_more"
|
||||
title:@"#+="
|
||||
output:@""
|
||||
type:KBKeyTypeSymbolsToggle];
|
||||
KBKey *comma = [KBKey keyWithTitle:@"," output:@","];
|
||||
KBKey *dot = [KBKey keyWithTitle:@"." output:@"."];
|
||||
KBKey *q = [KBKey keyWithTitle:@"?" output:@"?"];
|
||||
KBKey *ex = [KBKey keyWithTitle:@"!" output:@"!"];
|
||||
KBKey *quote = [KBKey keyWithTitle:@"'" output:@"'"];
|
||||
KBKey *back = [KBKey keyWithIdentifier:@"backspace"
|
||||
title:@"⌫"
|
||||
output:@""
|
||||
type:KBKeyTypeBackspace];
|
||||
r3 = @[ toggle, comma, dot, q, ex, quote, back ];
|
||||
} else {
|
||||
// 数字第二页(#+=):前两行替换为更多符号,左下角按钮文案改为“123”
|
||||
r1 = @[ [KBKey keyWithTitle:@"[" output:@"["], [KBKey keyWithTitle:@"]" output:@"]"], [KBKey keyWithTitle:@"{" output:@"{"],
|
||||
@@ -116,16 +141,40 @@
|
||||
[KBKey keyWithTitle:@"~" output:@"~"], [KBKey keyWithTitle:@"<" output:@"<"], [KBKey keyWithTitle:@">" output:@">"],
|
||||
[KBKey keyWithTitle:@"$" output:@"$"], [KBKey keyWithTitle:@"€" output:@"€"], [KBKey keyWithTitle:@"£" output:@"£"],
|
||||
[KBKey keyWithTitle:@"•" output:@"•"] ];
|
||||
r3 = @[ [KBKey keyWithTitle:@"123" type:KBKeyTypeSymbolsToggle],
|
||||
[KBKey keyWithTitle:@"," output:@","], [KBKey keyWithTitle:@"." output:@"."], [KBKey keyWithTitle:@"?" output:@"?"],
|
||||
[KBKey keyWithTitle:@"!" output:@"!"], [KBKey keyWithTitle:@"'" output:@"'"],
|
||||
[KBKey keyWithTitle:@"⌫" type:KBKeyTypeBackspace] ];
|
||||
KBKey *toggle = [KBKey keyWithIdentifier:@"symbols_toggle_123"
|
||||
title:@"123"
|
||||
output:@""
|
||||
type:KBKeyTypeSymbolsToggle];
|
||||
KBKey *comma = [KBKey keyWithTitle:@"," output:@","];
|
||||
KBKey *dot = [KBKey keyWithTitle:@"." output:@"."];
|
||||
KBKey *q = [KBKey keyWithTitle:@"?" output:@"?"];
|
||||
KBKey *ex = [KBKey keyWithTitle:@"!" output:@"!"];
|
||||
KBKey *quote = [KBKey keyWithTitle:@"'" output:@"'"];
|
||||
KBKey *back = [KBKey keyWithIdentifier:@"backspace"
|
||||
title:@"⌫"
|
||||
output:@""
|
||||
type:KBKeyTypeBackspace];
|
||||
r3 = @[ toggle, comma, dot, q, ex, quote, back ];
|
||||
}
|
||||
|
||||
NSArray *r4 = @[ [KBKey keyWithTitle:@"abc" type:KBKeyTypeModeChange],
|
||||
[KBKey keyWithTitle:@"AI" type:KBKeyTypeCustom],
|
||||
[KBKey keyWithTitle:@"space" type:KBKeyTypeSpace],
|
||||
[KBKey keyWithTitle:KBLocalized(@"Send") type:KBKeyTypeReturn] ];
|
||||
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];
|
||||
}
|
||||
@@ -139,27 +188,67 @@
|
||||
// 字母键标题与输出同时随 Shift 切换大小写,界面与输入保持一致
|
||||
for (NSString *s in r1) {
|
||||
NSString *shown = self.shiftOn ? s : s.lowercaseString;
|
||||
[row1 addObject:[KBKey keyWithTitle:shown output:shown]];
|
||||
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 *row2 = [NSMutableArray arrayWithCapacity:r2.count];
|
||||
for (NSString *s in r2) {
|
||||
NSString *shown = self.shiftOn ? s : s.lowercaseString;
|
||||
[row2 addObject:[KBKey keyWithTitle:shown output:shown]];
|
||||
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 *row3 = [NSMutableArray array];
|
||||
[row3 addObject:[KBKey keyWithTitle:@"⇧" type:KBKeyTypeShift]];
|
||||
KBKey *shift = [KBKey keyWithIdentifier:@"shift"
|
||||
title:@"⇧"
|
||||
output:@""
|
||||
type:KBKeyTypeShift];
|
||||
[row3 addObject:shift];
|
||||
for (NSString *s in r3chars) {
|
||||
NSString *shown = self.shiftOn ? s : s.lowercaseString;
|
||||
[row3 addObject:[KBKey keyWithTitle:shown output:shown]];
|
||||
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];
|
||||
}
|
||||
[row3 addObject:[KBKey keyWithTitle:@"⌫" type:KBKeyTypeBackspace]];
|
||||
KBKey *backspace = [KBKey keyWithIdentifier:@"backspace"
|
||||
title:@"⌫"
|
||||
output:@""
|
||||
type:KBKeyTypeBackspace];
|
||||
[row3 addObject:backspace];
|
||||
|
||||
NSArray *row4 = @[ [KBKey keyWithTitle:@"123" type:KBKeyTypeModeChange],
|
||||
[KBKey keyWithTitle:@"AI" type:KBKeyTypeCustom],
|
||||
[KBKey keyWithTitle:@"space" type:KBKeyTypeSpace],
|
||||
[KBKey keyWithTitle:KBLocalized(@"Send") type:KBKeyTypeReturn] ];
|
||||
KBKey *mode123 = [KBKey keyWithIdentifier:@"mode_123"
|
||||
title:@"123"
|
||||
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 *row4 = @[ mode123, customAI, space, ret ];
|
||||
|
||||
return @[row1.copy, row2.copy, row3.copy, row4];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user