2025-11-11 14:56:57 +08:00
|
|
|
|
//
|
|
|
|
|
|
// KBPersonInfoItemCell.m
|
|
|
|
|
|
// keyBoard
|
|
|
|
|
|
//
|
|
|
|
|
|
// Created by Codex on 2025/11/11.
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
|
|
@import UIKit;
|
|
|
|
|
|
#import "KBPersonInfoItemCell.h"
|
|
|
|
|
|
#import <Masonry/Masonry.h>
|
|
|
|
|
|
|
|
|
|
|
|
@interface KBPersonInfoItemCell ()
|
|
|
|
|
|
// 白色圆角容器(实现卡片效果)
|
|
|
|
|
|
@property (nonatomic, strong) UIView *cardView;
|
|
|
|
|
|
// 标题(左)
|
|
|
|
|
|
@property (nonatomic, strong) UILabel *titleLabel;
|
|
|
|
|
|
// 值(右)
|
|
|
|
|
|
@property (nonatomic, strong) UILabel *valueLabel;
|
|
|
|
|
|
// 箭头(>)
|
|
|
|
|
|
@property (nonatomic, strong) UIImageView *arrowView;
|
|
|
|
|
|
// 复制按钮
|
|
|
|
|
|
@property (nonatomic, strong) UIButton *copyBtn;
|
|
|
|
|
|
// 分割线
|
2025-11-11 15:13:43 +08:00
|
|
|
|
// 废弃分割线:按需求不显示底部分割线
|
2025-11-11 14:56:57 +08:00
|
|
|
|
// 记录圆角位置,layoutSubviews 时更新 mask
|
|
|
|
|
|
@property (nonatomic, assign) UIRectCorner cornerRecord;
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
@implementation KBPersonInfoItemCell
|
|
|
|
|
|
|
|
|
|
|
|
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
|
|
|
|
|
|
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
|
|
|
|
|
|
self.backgroundColor = UIColor.clearColor;
|
|
|
|
|
|
self.selectionStyle = UITableViewCellSelectionStyleNone;
|
|
|
|
|
|
|
|
|
|
|
|
[self.contentView addSubview:self.cardView];
|
|
|
|
|
|
[self.cardView addSubview:self.titleLabel];
|
|
|
|
|
|
[self.cardView addSubview:self.valueLabel];
|
|
|
|
|
|
[self.cardView addSubview:self.arrowView];
|
|
|
|
|
|
[self.cardView addSubview:self.copyBtn];
|
|
|
|
|
|
|
|
|
|
|
|
[self.cardView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
|
|
make.left.equalTo(self.contentView).offset(16);
|
|
|
|
|
|
make.right.equalTo(self.contentView).offset(-16);
|
|
|
|
|
|
make.top.equalTo(self.contentView);
|
|
|
|
|
|
make.bottom.equalTo(self.contentView);
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
[self.titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
|
|
make.left.equalTo(self.cardView).offset(16);
|
|
|
|
|
|
make.centerY.equalTo(self.cardView);
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
[self.arrowView mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
|
|
make.right.equalTo(self.cardView).offset(-16);
|
|
|
|
|
|
make.centerY.equalTo(self.cardView);
|
|
|
|
|
|
make.width.mas_equalTo(10);
|
|
|
|
|
|
make.height.mas_equalTo(16);
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
[self.copyBtn mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
|
|
make.centerY.equalTo(self.cardView);
|
|
|
|
|
|
make.right.equalTo(self.cardView).offset(-16);
|
|
|
|
|
|
make.width.height.mas_equalTo(22);
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
[self.valueLabel mas_makeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
|
|
make.centerY.equalTo(self.cardView);
|
|
|
|
|
|
make.right.equalTo(self.arrowView.mas_left).offset(-8);
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
2025-11-11 15:13:43 +08:00
|
|
|
|
// 不添加底部分割线
|
2025-11-11 14:56:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
return self;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)layoutSubviews {
|
|
|
|
|
|
[super layoutSubviews];
|
2025-11-11 15:13:43 +08:00
|
|
|
|
// 根据位置设置圆角:顶部或底部为 12,中间为 0
|
|
|
|
|
|
self.cardView.layer.cornerRadius = (self.cornerRecord != 0 ? 12.0 : 0.0);
|
2025-11-11 14:56:57 +08:00
|
|
|
|
// 根据记录的 corner 重新生成 mask,保证尺寸变化后仍正确
|
|
|
|
|
|
if (self.cornerRecord != 0 && !CGRectIsEmpty(self.cardView.bounds)) {
|
|
|
|
|
|
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.cardView.bounds
|
|
|
|
|
|
byRoundingCorners:self.cornerRecord
|
|
|
|
|
|
cornerRadii:CGSizeMake(12, 12)];
|
|
|
|
|
|
CAShapeLayer *mask = [CAShapeLayer layer];
|
|
|
|
|
|
mask.frame = self.cardView.bounds; mask.path = path.CGPath;
|
|
|
|
|
|
self.cardView.layer.mask = mask;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
self.cardView.layer.mask = nil;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)prepareForReuse {
|
|
|
|
|
|
[super prepareForReuse];
|
|
|
|
|
|
self.arrowView.hidden = YES; self.copyBtn.hidden = YES;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (void)configWithTitle:(NSString *)title
|
|
|
|
|
|
value:(NSString *)value
|
|
|
|
|
|
showArrow:(BOOL)showArrow
|
|
|
|
|
|
showCopy:(BOOL)showCopy
|
|
|
|
|
|
isTop:(BOOL)isTop
|
|
|
|
|
|
isBottom:(BOOL)isBottom {
|
|
|
|
|
|
self.titleLabel.text = title ?: @"";
|
|
|
|
|
|
self.valueLabel.text = value ?: @"";
|
|
|
|
|
|
self.arrowView.hidden = !showArrow;
|
|
|
|
|
|
self.copyBtn.hidden = !showCopy;
|
|
|
|
|
|
self.valueLabel.textColor = showArrow ? [UIColor blackColor] : [UIColor colorWithWhite:0.2 alpha:1.0];
|
|
|
|
|
|
|
|
|
|
|
|
// 当显示复制按钮时,值需要靠左到复制按钮左侧
|
|
|
|
|
|
UIView *rightAnchor = showCopy ? self.copyBtn : self.arrowView;
|
|
|
|
|
|
[self.valueLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
|
|
|
|
|
make.centerY.equalTo(self.cardView);
|
|
|
|
|
|
make.right.equalTo(rightAnchor.mas_left).offset(-8);
|
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
|
|
// 顶部/底部圆角控制 + 分割线
|
|
|
|
|
|
UIRectCorner corners = 0;
|
|
|
|
|
|
if (isTop && isBottom) {
|
|
|
|
|
|
corners = UIRectCornerAllCorners;
|
|
|
|
|
|
} else if (isTop) {
|
|
|
|
|
|
corners = UIRectCornerTopLeft | UIRectCornerTopRight;
|
|
|
|
|
|
} else if (isBottom) {
|
|
|
|
|
|
corners = UIRectCornerBottomLeft | UIRectCornerBottomRight;
|
|
|
|
|
|
} else {
|
2025-11-11 15:13:43 +08:00
|
|
|
|
corners = 0;
|
2025-11-11 14:56:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 使用遮罩实现指定圆角
|
|
|
|
|
|
// 记录并等待 layoutSubviews 里按实际尺寸设置 mask
|
|
|
|
|
|
self.cornerRecord = corners;
|
|
|
|
|
|
[self setNeedsLayout];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#pragma mark - Lazy UI
|
|
|
|
|
|
|
|
|
|
|
|
- (UIView *)cardView {
|
|
|
|
|
|
if (!_cardView) {
|
|
|
|
|
|
_cardView = [UIView new];
|
|
|
|
|
|
_cardView.backgroundColor = UIColor.whiteColor;
|
2025-11-11 15:13:43 +08:00
|
|
|
|
_cardView.layer.cornerRadius = 0.0; // 具体圆角在 layoutSubviews 中按位置设置
|
2025-11-11 14:56:57 +08:00
|
|
|
|
_cardView.layer.masksToBounds = YES; // 配合圆角
|
|
|
|
|
|
}
|
|
|
|
|
|
return _cardView;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (UILabel *)titleLabel {
|
|
|
|
|
|
if (!_titleLabel) {
|
|
|
|
|
|
_titleLabel = [UILabel new];
|
2025-11-11 15:13:43 +08:00
|
|
|
|
_titleLabel.textColor = [UIColor colorWithHex:KBBlackValue];
|
2025-11-11 14:56:57 +08:00
|
|
|
|
_titleLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightRegular];
|
|
|
|
|
|
}
|
|
|
|
|
|
return _titleLabel;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (UILabel *)valueLabel {
|
|
|
|
|
|
if (!_valueLabel) {
|
|
|
|
|
|
_valueLabel = [UILabel new];
|
2025-11-11 15:13:43 +08:00
|
|
|
|
_valueLabel.textColor = [UIColor colorWithHex:KBBlackValue];
|
2025-11-11 14:56:57 +08:00
|
|
|
|
_valueLabel.font = [UIFont systemFontOfSize:16 weight:UIFontWeightSemibold];
|
|
|
|
|
|
_valueLabel.textAlignment = NSTextAlignmentRight;
|
|
|
|
|
|
[_valueLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisHorizontal];
|
|
|
|
|
|
}
|
|
|
|
|
|
return _valueLabel;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (UIImageView *)arrowView {
|
|
|
|
|
|
if (!_arrowView) {
|
|
|
|
|
|
_arrowView = [[UIImageView alloc] init];
|
|
|
|
|
|
_arrowView.contentMode = UIViewContentModeScaleAspectFit;
|
|
|
|
|
|
UIImage *img = nil;
|
|
|
|
|
|
if (@available(iOS 13.0, *)) {
|
|
|
|
|
|
img = [UIImage systemImageNamed:@"chevron.right"];
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!img) {
|
|
|
|
|
|
// 简易绘制一个三角箭头作为兜底
|
|
|
|
|
|
CGSize size = CGSizeMake(10, 16);
|
|
|
|
|
|
UIGraphicsBeginImageContextWithOptions(size, NO, 0);
|
|
|
|
|
|
UIBezierPath *p = [UIBezierPath bezierPath];
|
|
|
|
|
|
[p moveToPoint:CGPointMake(2, 2)];
|
|
|
|
|
|
[p addLineToPoint:CGPointMake(8, 8)];
|
|
|
|
|
|
[p addLineToPoint:CGPointMake(2, 14)];
|
|
|
|
|
|
[[UIColor colorWithWhite:0.7 alpha:1] setStroke];
|
|
|
|
|
|
p.lineWidth = 2; [p stroke];
|
|
|
|
|
|
img = UIGraphicsGetImageFromCurrentImageContext();
|
|
|
|
|
|
UIGraphicsEndImageContext();
|
|
|
|
|
|
}
|
|
|
|
|
|
_arrowView.image = img;
|
|
|
|
|
|
_arrowView.tintColor = [UIColor colorWithWhite:0.7 alpha:1];
|
|
|
|
|
|
_arrowView.hidden = YES;
|
|
|
|
|
|
}
|
|
|
|
|
|
return _arrowView;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (UIButton *)copyBtn {
|
|
|
|
|
|
if (!_copyBtn) {
|
|
|
|
|
|
_copyBtn = [UIButton buttonWithType:UIButtonTypeSystem];
|
|
|
|
|
|
UIImage *img = nil;
|
|
|
|
|
|
if (@available(iOS 13.0, *)) {
|
|
|
|
|
|
img = [UIImage systemImageNamed:@"doc.on.doc"];
|
|
|
|
|
|
}
|
|
|
|
|
|
if (!img) {
|
|
|
|
|
|
// 兜底绘制一个简单的 copy 图标
|
|
|
|
|
|
CGSize sz = CGSizeMake(22, 22);
|
|
|
|
|
|
UIGraphicsBeginImageContextWithOptions(sz, NO, 0);
|
|
|
|
|
|
CGContextRef ctx = UIGraphicsGetCurrentContext();
|
|
|
|
|
|
[[UIColor colorWithWhite:0.85 alpha:1] setStroke];
|
|
|
|
|
|
CGContextSetLineWidth(ctx, 2);
|
|
|
|
|
|
CGContextStrokeRect(ctx, CGRectMake(6, 6, 12, 12));
|
|
|
|
|
|
CGContextStrokeRect(ctx, CGRectMake(4, 4, 12, 12));
|
|
|
|
|
|
img = UIGraphicsGetImageFromCurrentImageContext();
|
|
|
|
|
|
UIGraphicsEndImageContext();
|
|
|
|
|
|
}
|
|
|
|
|
|
[_copyBtn setImage:img forState:UIControlStateNormal];
|
|
|
|
|
|
_copyBtn.tintColor = [UIColor colorWithWhite:0.6 alpha:1];
|
|
|
|
|
|
_copyBtn.hidden = YES;
|
|
|
|
|
|
[_copyBtn addTarget:self action:@selector(onCopy) forControlEvents:UIControlEventTouchUpInside];
|
|
|
|
|
|
}
|
|
|
|
|
|
return _copyBtn;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-11-11 15:13:43 +08:00
|
|
|
|
// 无分割线
|
2025-11-11 14:56:57 +08:00
|
|
|
|
|
|
|
|
|
|
#pragma mark - Event
|
|
|
|
|
|
|
|
|
|
|
|
- (void)onCopy {
|
|
|
|
|
|
// 简单示例:复制 valueLabel 文本
|
|
|
|
|
|
NSString *txt = self.valueLabel.text ?: @"";
|
|
|
|
|
|
if (txt.length == 0) return;
|
|
|
|
|
|
UIPasteboard.generalPasteboard.string = txt;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@end
|