// // MySkinCell.m // keyBoard // #import "MySkinCell.h" #import #import "UIColor+Extension.h" // 左上角小圆点 + 对勾视图(无需切图,用 CAShapeLayer 绘制) @interface KBSelectDotView : UIView @property (nonatomic, assign) BOOL selectedState; // 选中状态 - (void)applySelected:(BOOL)selected; // 刷新外观 @end @implementation KBSelectDotView { CAShapeLayer *_circleLayer; // 圆形背景 CAShapeLayer *_checkLayer; // 白色对勾 } - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.backgroundColor = UIColor.clearColor; _circleLayer = [CAShapeLayer layer]; _circleLayer.fillColor = [UIColor colorWithWhite:0 alpha:0.51].CGColor; // 默认未选中:#000000 51% [self.layer addSublayer:_circleLayer]; _checkLayer = [CAShapeLayer layer]; _checkLayer.strokeColor = UIColor.whiteColor.CGColor; // 对勾白色 _checkLayer.fillColor = UIColor.clearColor.CGColor; _checkLayer.lineWidth = 2.0; _checkLayer.lineCap = kCALineCapRound; _checkLayer.lineJoin = kCALineJoinRound; _checkLayer.hidden = YES; // 未选中时隐藏 [self.layer addSublayer:_checkLayer]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; CGFloat size = MIN(self.bounds.size.width, self.bounds.size.height); CGRect r = CGRectMake((self.bounds.size.width - size) * 0.5, (self.bounds.size.height - size) * 0.5, size, size); UIBezierPath *circle = [UIBezierPath bezierPathWithOvalInRect:r]; _circleLayer.path = circle.CGPath; // 对勾路径(相对 size) CGFloat s = size; CGPoint p1 = CGPointMake(CGRectGetMinX(r) + s * 0.26, CGRectGetMinY(r) + s * 0.55); CGPoint p2 = CGPointMake(CGRectGetMinX(r) + s * 0.43, CGRectGetMinY(r) + s * 0.72); CGPoint p3 = CGPointMake(CGRectGetMinX(r) + s * 0.76, CGRectGetMinY(r) + s * 0.28); UIBezierPath *check = [UIBezierPath bezierPath]; [check moveToPoint:p1]; [check addLineToPoint:p2]; [check addLineToPoint:p3]; _checkLayer.path = check.CGPath; } - (void)applySelected:(BOOL)selected { self.selectedState = selected; UIColor *fill = selected ? [UIColor colorWithHex:KBColor] : [UIColor colorWithWhite:0 alpha:0.51]; _circleLayer.fillColor = fill.CGColor; // 选中改为 #02BEAC _checkLayer.hidden = !selected; // 选中显示白对勾 } @end @interface MySkinCell () @property (nonatomic, strong) UIView *cardView; // 卡片容器(圆角) @property (nonatomic, strong) UIImageView *coverView; // 预览图 @property (nonatomic, strong) UILabel *titleLabel; // 标题 @property (nonatomic, strong) KBSelectDotView *markView; // 左上角勾选图标(自绘) @end @implementation MySkinCell - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.contentView.backgroundColor = [UIColor whiteColor]; [self.contentView addSubview:self.cardView]; [self.cardView addSubview:self.coverView]; [self.cardView addSubview:self.titleLabel]; [self.contentView addSubview:self.markView]; [self.cardView mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.contentView); }]; [self.coverView mas_makeConstraints:^(MASConstraintMaker *make) { make.top.left.right.equalTo(self.cardView); make.height.equalTo(self.cardView.mas_width).multipliedBy(0.66); // 接近截图比例 }]; [self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.cardView).offset(12); make.right.equalTo(self.cardView).offset(-12); make.top.equalTo(self.coverView.mas_bottom).offset(10); }]; [self.markView mas_makeConstraints:^(MASConstraintMaker *make) { // 直接相对 contentView,避免受 cardView/masksToBounds 等影响 make.left.equalTo(self.contentView).offset(8); make.top.equalTo(self.contentView).offset(8); make.width.height.mas_equalTo(15); // 设计要求:直径 15px }]; self.markView.hidden = YES; // 默认非编辑态隐藏 } return self; } - (void)prepareForReuse { [super prepareForReuse]; self.editing = NO; [self updateSelected:NO]; } - (void)setSelected:(BOOL)selected { [super setSelected:selected]; // 统一在系统选中态变更时同步小圆点 [self updateSelected:selected]; } - (void)configWithTitle:(NSString *)title image:(UIImage *)image { self.titleLabel.text = title.length ? title : @"Dopamine"; // 简化:展示本地占位色 self.coverView.backgroundColor = [UIColor colorWithWhite:0.92 alpha:1.0]; } - (void)setEditing:(BOOL)editing { _editing = editing; self.markView.hidden = !editing; if (editing) { [self.markView applySelected:self.isSelected]; } } - (void)updateSelected:(BOOL)selected { if (!self.isEditing) { self.markView.hidden = YES; return; } self.markView.hidden = NO; [self.markView applySelected:selected]; } #pragma mark - Lazy - (UIView *)cardView { if (!_cardView) { _cardView = [UIView new]; _cardView.backgroundColor = [UIColor colorWithWhite:0.97 alpha:1.0]; _cardView.layer.cornerRadius = 12; _cardView.layer.masksToBounds = YES; } return _cardView; } - (UIImageView *)coverView { if (!_coverView) { _coverView = [[UIImageView alloc] init]; _coverView.contentMode = UIViewContentModeScaleAspectFill; _coverView.clipsToBounds = YES; } return _coverView; } - (UILabel *)titleLabel { if (!_titleLabel) { _titleLabel = [UILabel new]; _titleLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightSemibold]; _titleLabel.textColor = [UIColor colorWithHex:0x333333]; _titleLabel.text = @"Dopamine"; } return _titleLabel; } - (KBSelectDotView *)markView { if (!_markView) { _markView = [[KBSelectDotView alloc] init]; _markView.userInteractionEnabled = NO; // 只作展示 _markView.layer.zPosition = 10; // 置顶,确保不被图片遮挡 } return _markView; } @end