// // 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 *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 *)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