// // KBMyKeyboardCell.m // keyBoard // #import "KBMyKeyboardCell.h" @interface KBMyKeyboardCell () @property (nonatomic, strong) UIView *coverView; // 左侧表情 @property (nonatomic, strong) UILabel *emojiLabel; // 左侧表情 @property (nonatomic, strong) UILabel *titleLabel; // 标题 @property (nonatomic, strong) UIView *minusBadge; // 右上角减号圆点 @property (nonatomic, strong) UILabel *minusLabel; // 减号 @property (nonatomic, strong) UIControl *minusTapArea; // 放大点击区域(透明) @end @implementation KBMyKeyboardCell - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.contentView.backgroundColor = [UIColor clearColor]; // 轻微阴影,让卡片更立体 self.layer.shadowColor = [UIColor colorWithWhite:0 alpha:0.08].CGColor; self.layer.shadowOpacity = 1.0; self.layer.shadowOffset = CGSizeMake(0, 2); self.layer.shadowRadius = 6; [self.contentView addSubview:self.coverView]; [self.coverView addSubview:self.emojiLabel]; [self.coverView addSubview:self.titleLabel]; [self.contentView addSubview:self.minusBadge]; [self.minusBadge addSubview:self.minusLabel]; [self.coverView mas_makeConstraints:^(MASConstraintMaker *make) { make.bottom.left.equalTo(self.contentView).offset(0); make.height.mas_equalTo(36); }]; // Masonry 布局:左右 12 内边距,高度固定由外部控制 [self.emojiLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.coverView).offset(12); make.centerY.equalTo(self.coverView); }]; [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.emojiLabel.mas_right).offset(8); make.centerY.equalTo(self.coverView); make.right.lessThanOrEqualTo(self.coverView).offset(-12); }]; // 右上角删除圆点(展示用),默认显示;如需编辑态控制,可对其 hidden 做处理 [self.minusBadge mas_makeConstraints:^(MASConstraintMaker *make) { make.width.height.mas_equalTo(11); make.top.equalTo(self.contentView).offset(0); make.right.equalTo(self.contentView).offset(0); }]; [self.minusLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.center.equalTo(self.minusBadge); }]; // 点击右上角减号:在其上方覆盖一层更大的透明点击区域,提升可点性 [self.contentView addSubview:self.minusTapArea]; [self.minusTapArea mas_makeConstraints:^(MASConstraintMaker *make) { make.top.equalTo(self.contentView).offset(0); make.right.equalTo(self.contentView).offset(0); make.width.height.mas_equalTo(32); // 扩大到 32x32,更易点中 }]; // 将可点事件绑定到透明区域;保留 minusBadge 的手势作为兜底 [self.minusTapArea addTarget:self action:@selector(didTapMinus) forControlEvents:UIControlEventTouchUpInside]; self.minusBadge.userInteractionEnabled = YES; UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapMinus)]; [self.minusBadge addGestureRecognizer:tap]; } return self; } - (void)prepareForReuse { [super prepareForReuse]; self.emojiLabel.text = @""; self.titleLabel.text = @""; } - (void)configEmoji:(NSString *)emoji title:(NSString *)title { // 配置 UI 文案(为空补空串,避免计算崩溃) self.emojiLabel.text = emoji ?: @""; self.titleLabel.text = title ?: @""; } + (CGSize)sizeForEmoji:(NSString *)emoji title:(NSString *)title { // 固定高度 44,宽度 = 左右内边距(12+12) + Emoji 宽(按 20 号字估算) + 间距(8) + 文案宽 UIFont *emojiFont = [UIFont systemFontOfSize:20]; UIFont *titleFont = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; CGFloat emojiW = 0; if (emoji.length > 0) { CGSize s = [emoji sizeWithAttributes:@{NSFontAttributeName:emojiFont}]; emojiW = ceil(s.width); } else { emojiW = 0; // 没有表情则不占宽 } CGFloat textW = 0; if (title.length > 0) { CGSize s = [title sizeWithAttributes:@{NSFontAttributeName:titleFont}]; textW = ceil(s.width); } CGFloat width = 12 + emojiW + (emojiW > 0 ? 8 : 0) + textW + 12; CGFloat minW = 84; // 最小宽保证视觉 CGFloat maxW = UIScreen.mainScreen.bounds.size.width - 16 * 2; // 不超过屏幕可视宽 width = MAX(minW, MIN(width, maxW)); return CGSizeMake(width, 41.0); } #pragma mark - Lazy - (UILabel *)emojiLabel { if (!_emojiLabel) { _emojiLabel = [UILabel new]; _emojiLabel.font = [UIFont systemFontOfSize:20]; _emojiLabel.text = @"😀"; // 默认 } return _emojiLabel; } - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [UILabel new]; _titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold]; _titleLabel.textColor = [UIColor colorWithHex:0x1B1F1A]; } return _titleLabel; } - (UIView *)minusBadge { if (!_minusBadge) { _minusBadge = [UIView new]; _minusBadge.backgroundColor = [UIColor colorWithHex:KBColorValue]; _minusBadge.layer.cornerRadius = 5.5; _minusBadge.layer.masksToBounds = YES; } return _minusBadge; } - (UILabel *)minusLabel { if (!_minusLabel) { _minusLabel = [UILabel new]; _minusLabel.text = @"-"; _minusLabel.textColor = [UIColor whiteColor]; _minusLabel.font = [UIFont systemFontOfSize:12 weight:UIFontWeightBold]; _minusLabel.textAlignment = NSTextAlignmentCenter; } return _minusLabel; } - (UIControl *)minusTapArea { if (!_minusTapArea) { _minusTapArea = [[UIControl alloc] init]; _minusTapArea.backgroundColor = [UIColor clearColor]; // 提高命中率:即使轻微偏离也能点中 _minusTapArea.accessibilityLabel = KBLocalized(@"Delete"); } return _minusTapArea; } - (UIView *)coverView{ if (!_coverView) { _coverView = [[UIView alloc] init]; _coverView.backgroundColor = [UIColor whiteColor]; _coverView.layer.cornerRadius = 4; _coverView.layer.masksToBounds = true; } return _coverView; } #pragma mark - Actions // 触发减号点击回调,由外部(VC)决定是否弹框与删除数据 - (void)didTapMinus { if (self.onMinusTapped) { self.onMinusTapped(self); } } @end