优化键盘弹出宽度
优化键盘按钮视觉效果
This commit is contained in:
@@ -10,12 +10,23 @@
|
||||
@interface KBKeyButton ()
|
||||
// 内部缓存:便于从按钮查找到所属的 KBKeyboardView
|
||||
@property (nonatomic, weak, readonly) UIView *kb_keyboardContainer;
|
||||
@property (nonatomic, strong) UIImageView *normalImageView; /// 没有皮肤的时候展示
|
||||
@property (nonatomic, strong) UIColor *baseBackgroundColor; /// 无按下状态下,由皮肤/主题决定的底色(由 normalImageView 展示)
|
||||
|
||||
@end
|
||||
|
||||
@implementation KBKeyButton
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
[self addSubview:self.normalImageView];
|
||||
self.normalImageView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[NSLayoutConstraint activateConstraints:@[
|
||||
[self.normalImageView.topAnchor constraintEqualToAnchor:self.topAnchor],
|
||||
[self.normalImageView.bottomAnchor constraintEqualToAnchor:self.bottomAnchor],
|
||||
[self.normalImageView.leadingAnchor constraintEqualToAnchor:self.leadingAnchor constant:2],
|
||||
[self.normalImageView.trailingAnchor constraintEqualToAnchor:self.trailingAnchor constant:-2],
|
||||
]];
|
||||
[self applyDefaultStyle];
|
||||
}
|
||||
return self;
|
||||
@@ -26,13 +37,16 @@
|
||||
KBSkinTheme *t = [KBSkinManager shared].current;
|
||||
[self setTitleColor:t.keyTextColor forState:UIControlStateNormal];
|
||||
[self setTitleColor:t.keyTextColor forState:UIControlStateHighlighted];
|
||||
self.backgroundColor = t.keyBackground;
|
||||
// 颜色由 normalImageView 控制,按钮本身保持透明,避免叠加背景影响视觉
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.layer.cornerRadius = 6.0; // 圆角
|
||||
self.layer.masksToBounds = NO;
|
||||
self.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.1].CGColor; // 阴影效果
|
||||
self.layer.shadowOpacity = 1.0;
|
||||
self.layer.shadowOffset = CGSizeMake(0, 1);
|
||||
self.layer.shadowRadius = 1.5;
|
||||
|
||||
// 初始状态下根据主题设置底色(给没有皮肤图的按键使用)
|
||||
[self refreshStateAppearance];
|
||||
|
||||
// 懒创建图标视图,用于后续皮肤按键小图标展示
|
||||
@@ -67,10 +81,19 @@
|
||||
// 按下时整体做一个等比缩放动画,不改背景色和透明度。
|
||||
// 这样无论是纯文字键还是整块皮肤图,都有统一的“按下”视觉反馈。
|
||||
CGFloat scale = highlighted ? 0.9 : 1.0; // 可根据手感微调 0.9~0.95
|
||||
|
||||
// 没有皮肤图片时,normalImageView 做灰度按下效果
|
||||
BOOL hasIcon = (self.iconView.image != nil);
|
||||
UIColor *normalBgColor = self.baseBackgroundColor ?: [UIColor whiteColor];
|
||||
UIColor *highlightBgColor = [self kb_darkerColorForColor:normalBgColor];
|
||||
|
||||
[UIView animateWithDuration:0.08
|
||||
delay:0
|
||||
options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut
|
||||
animations:^{
|
||||
if (!hasIcon && !self.normalImageView.hidden) {
|
||||
self.normalImageView.backgroundColor = highlighted ? highlightBgColor : normalBgColor;
|
||||
}
|
||||
self.transform = CGAffineTransformMakeScale(scale, scale);
|
||||
}
|
||||
completion:nil];
|
||||
@@ -101,11 +124,26 @@
|
||||
- (void)refreshStateAppearance {
|
||||
// 选中态用于 Shift/CapsLock 等特殊按键的高亮显示
|
||||
KBSkinTheme *t = [KBSkinManager shared].current;
|
||||
UIColor *base = nil;
|
||||
if (self.isSelected) {
|
||||
self.backgroundColor = t.keyHighlightBackground ?: t.keyBackground;
|
||||
base = t.keyHighlightBackground ?: t.keyBackground;
|
||||
} else {
|
||||
self.backgroundColor = t.keyBackground;
|
||||
base = t.keyBackground;
|
||||
}
|
||||
if (!base) {
|
||||
base = [UIColor whiteColor];
|
||||
}
|
||||
|
||||
self.baseBackgroundColor = base;
|
||||
// 按键背景统一由 normalImageView 控制,按钮本身透明
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
|
||||
// 有皮肤图时仅展示 icon,不再显示普通背景色
|
||||
if (self.iconView.image != nil || self.normalImageView.hidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.normalImageView.backgroundColor = base;
|
||||
}
|
||||
|
||||
- (void)applyThemeForCurrentKey {
|
||||
@@ -121,16 +159,14 @@
|
||||
self.iconView.hidden = (iconImg == nil);
|
||||
|
||||
BOOL hasIcon = (iconImg != nil);
|
||||
|
||||
self.normalImageView.hidden = hasIcon;
|
||||
if (hasIcon) {
|
||||
// 有图标:仅显示图片,完全隐藏文字
|
||||
[self setTitle:@"" forState:UIControlStateNormal];
|
||||
[self setTitle:@"" forState:UIControlStateHighlighted];
|
||||
[self setTitle:@"" forState:UIControlStateSelected];
|
||||
self.titleLabel.hidden = YES;
|
||||
KBSkinTheme *t = [KBSkinManager shared].current;
|
||||
t.keyBackground = [UIColor clearColor];
|
||||
|
||||
self.normalImageView.backgroundColor = [UIColor clearColor];
|
||||
} else {
|
||||
// 无图标:按键标题正常显示(使用 key.title),并根据 hidden_keys 决定要不要隐藏
|
||||
[self setTitle:self.key.title forState:UIControlStateNormal];
|
||||
@@ -139,6 +175,34 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (UIImageView *)normalImageView{
|
||||
if (!_normalImageView) {
|
||||
_normalImageView = [[UIImageView alloc] init];
|
||||
// 初始给一个默认色,后续会由 refreshStateAppearance / 皮肤统一覆盖
|
||||
_normalImageView.backgroundColor = [UIColor whiteColor];
|
||||
_normalImageView.layer.cornerRadius = 6;
|
||||
_normalImageView.layer.masksToBounds = true;
|
||||
}
|
||||
return _normalImageView;
|
||||
}
|
||||
|
||||
/// 在当前底色的基础上略微变暗,作为按下时的“灰度”效果
|
||||
- (UIColor *)kb_darkerColorForColor:(UIColor *)color {
|
||||
if (!color) return [UIColor colorWithWhite:0.9 alpha:1.0];
|
||||
|
||||
CGFloat h = 0, s = 0, b = 0, a = 0;
|
||||
if ([color getHue:&h saturation:&s brightness:&b alpha:&a]) {
|
||||
return [UIColor colorWithHue:h saturation:s brightness:MAX(b * 0.9, 0.0) alpha:a];
|
||||
}
|
||||
|
||||
CGFloat white = 0;
|
||||
if ([color getWhite:&white alpha:&a]) {
|
||||
return [UIColor colorWithWhite:MAX(white * 0.9, 0.0) alpha:a];
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation KBKeyButton (KBKeyboardContainer)
|
||||
|
||||
@@ -620,7 +620,8 @@ edgeSpacerMultiplier:(CGFloat)edgeSpacerMultiplier {
|
||||
|
||||
// 计算预览视图位置:在按钮上方稍微偏上
|
||||
CGRect btnFrameInSelf = [button convertRect:button.bounds toView:self];
|
||||
CGFloat previewWidth = MAX(CGRectGetWidth(btnFrameInSelf) * 1.4, 42.0);
|
||||
// CGFloat previewWidth = MAX(CGRectGetWidth(btnFrameInSelf) * 1.4, 42.0);
|
||||
CGFloat previewWidth = 42;
|
||||
CGFloat previewHeight = CGRectGetHeight(btnFrameInSelf) * 1.2;
|
||||
CGFloat centerX = CGRectGetMidX(btnFrameInSelf);
|
||||
CGFloat centerY = CGRectGetMinY(btnFrameInSelf) - previewHeight * 0.6;
|
||||
|
||||
Reference in New Issue
Block a user