Files
keyboard/CustomKeyboard/View/KBSuggestionBarView.m
2026-03-06 10:45:13 +08:00

195 lines
6.8 KiB
Objective-C

//
// KBSuggestionBarView.m
// CustomKeyboard
//
#import "KBSuggestionBarView.h"
#import "Masonry.h"
#import "KBSkinManager.h"
@interface KBSuggestionBarView ()
@property (nonatomic, strong) UIStackView *stackView;
@property (nonatomic, strong) UIView *topLineView;
@property (nonatomic, strong) UIView *bottomLineView;
@property (nonatomic, copy) NSArray<NSString *> *items;
@property (nonatomic, strong) UIColor *textColor;
@property (nonatomic, strong) UIColor *separatorColor;
@property (nonatomic, strong) UIColor *highlightColor;
@end
@implementation KBSuggestionBarView
- (NSInteger)kb_buttonTag {
return 10001;
}
- (NSInteger)kb_separatorTag {
return 10002;
}
- (UIImage *)kb_imageWithColor:(UIColor *)color {
if (!color) { color = [UIColor clearColor]; }
CGRect rect = CGRectMake(0, 0, 1, 1);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, color.CGColor);
CGContextFillRect(ctx, rect);
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor clearColor];
[self setupUI];
}
return self;
}
- (void)setupUI {
[self addSubview:self.stackView];
[self.stackView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self);
make.top.equalTo(self);
make.bottom.equalTo(self);
}];
[self addSubview:self.topLineView];
[self.topLineView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.top.equalTo(self);
make.height.mas_equalTo(0.5);
}];
[self addSubview:self.bottomLineView];
[self.bottomLineView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.bottom.equalTo(self);
make.height.mas_equalTo(0.5);
}];
[self applyTheme:[KBSkinManager shared].current];
}
- (void)updateSuggestions:(NSArray<NSString *> *)suggestions {
self.items = suggestions ?: @[];
for (UIView *view in self.stackView.arrangedSubviews) {
[self.stackView removeArrangedSubview:view];
[view removeFromSuperview];
}
NSUInteger count = self.items.count;
for (NSUInteger idx = 0; idx < count; idx++) {
NSString *item = self.items[idx];
UIView *container = [UIView new];
container.backgroundColor = UIColor.clearColor;
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.tag = [self kb_buttonTag];
btn.backgroundColor = UIColor.clearColor;
btn.layer.cornerRadius = 8.0;
btn.layer.masksToBounds = YES;
btn.adjustsImageWhenHighlighted = NO;
btn.titleLabel.font = [UIFont systemFontOfSize:15 weight:UIFontWeightRegular];
btn.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
btn.titleLabel.adjustsFontSizeToFitWidth = YES;
btn.titleLabel.minimumScaleFactor = 0.85;
btn.contentEdgeInsets = UIEdgeInsetsMake(0, 12, 0, 12);
[btn setTitle:item forState:UIControlStateNormal];
[btn setTitleColor:self.textColor ?: UIColor.blackColor forState:UIControlStateNormal];
if (self.highlightColor) {
[btn setBackgroundImage:[self kb_imageWithColor:self.highlightColor] forState:UIControlStateHighlighted];
}
[btn addTarget:self action:@selector(onTapSuggestion:) forControlEvents:UIControlEventTouchUpInside];
[container addSubview:btn];
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.equalTo(container);
}];
if (idx + 1 < count) {
UIView *sep = [UIView new];
sep.tag = [self kb_separatorTag];
sep.userInteractionEnabled = NO;
sep.backgroundColor = self.separatorColor ?: [UIColor colorWithWhite:0 alpha:0.12];
[container addSubview:sep];
[sep mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(container.mas_right);
make.centerY.equalTo(container.mas_centerY);
make.width.mas_equalTo(0.5);
make.height.equalTo(container.mas_height).multipliedBy(0.55);
}];
}
[self.stackView addArrangedSubview:container];
}
self.hidden = (self.items.count == 0);
}
- (void)applyTheme:(KBSkinTheme *)theme {
UIColor *barBg = theme.keyboardBackground ?: [UIColor colorWithWhite:0.95 alpha:1.0];
UIColor *text = theme.keyTextColor ?: UIColor.blackColor;
UIColor *highlight = theme.keyHighlightBackground ?: [UIColor colorWithWhite:0.85 alpha:1.0];
self.backgroundColor = barBg;
self.textColor = text;
self.separatorColor = [text colorWithAlphaComponent:0.12];
self.highlightColor = [highlight colorWithAlphaComponent:0.25];
self.topLineView.backgroundColor = [text colorWithAlphaComponent:0.08];
self.bottomLineView.backgroundColor = [text colorWithAlphaComponent:0.06];
for (UIView *view in self.stackView.arrangedSubviews) {
UIButton *btn = (UIButton *)[view viewWithTag:[self kb_buttonTag]];
if ([btn isKindOfClass:UIButton.class]) {
[btn setTitleColor:self.textColor ?: UIColor.blackColor forState:UIControlStateNormal];
[btn setBackgroundImage:[self kb_imageWithColor:self.highlightColor] forState:UIControlStateHighlighted];
}
UIView *sep = [view viewWithTag:[self kb_separatorTag]];
if (sep) {
sep.backgroundColor = self.separatorColor ?: [UIColor colorWithWhite:0 alpha:0.12];
}
}
}
#pragma mark - Actions
- (void)onTapSuggestion:(UIButton *)sender {
NSString *title = sender.currentTitle ?: @"";
if (title.length == 0) { return; }
if ([self.delegate respondsToSelector:@selector(suggestionBarView:didSelectSuggestion:)]) {
[self.delegate suggestionBarView:self didSelectSuggestion:title];
}
}
#pragma mark - Lazy
- (UIStackView *)stackView {
if (!_stackView) {
_stackView = [[UIStackView alloc] init];
_stackView.axis = UILayoutConstraintAxisHorizontal;
_stackView.alignment = UIStackViewAlignmentFill;
_stackView.distribution = UIStackViewDistributionFillEqually;
_stackView.spacing = 0.0;
_stackView.layoutMarginsRelativeArrangement = YES;
_stackView.layoutMargins = UIEdgeInsetsMake(0, 8, 0, 8);
}
return _stackView;
}
- (UIView *)topLineView {
if (!_topLineView) {
_topLineView = [UIView new];
_topLineView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.06];
}
return _topLineView;
}
- (UIView *)bottomLineView {
if (!_bottomLineView) {
_bottomLineView = [UIView new];
_bottomLineView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.04];
}
return _bottomLineView;
}
@end