201 lines
6.0 KiB
Objective-C
201 lines
6.0 KiB
Objective-C
//
|
||
// KBChatMessageActionPopView.m
|
||
// keyBoard
|
||
//
|
||
// Created by Codex on 2026/2/3.
|
||
//
|
||
|
||
#import "KBChatMessageActionPopView.h"
|
||
#import <Masonry/Masonry.h>
|
||
|
||
static CGFloat const kKBChatActionRowHeight = 52.0;
|
||
|
||
@interface KBChatMessageActionPopView ()
|
||
|
||
@property (nonatomic, strong) UIControl *copyRow;
|
||
@property (nonatomic, strong) UIControl *deleteRow;
|
||
@property (nonatomic, strong) UIControl *reportRow;
|
||
@property (nonatomic, strong) UIView *line1;
|
||
@property (nonatomic, strong) UIView *line2;
|
||
|
||
@end
|
||
|
||
@implementation KBChatMessageActionPopView
|
||
|
||
+ (CGFloat)preferredHeightWithShowsReportAction:(BOOL)showsReportAction {
|
||
// 2 行:Copy + Delete
|
||
// 3 行:Copy + Delete + Report
|
||
NSInteger rows = showsReportAction ? 3 : 2;
|
||
NSInteger lines = showsReportAction ? 2 : 1;
|
||
return kKBChatActionRowHeight * rows + 0.5 * lines;
|
||
}
|
||
|
||
- (instancetype)initWithFrame:(CGRect)frame {
|
||
self = [super initWithFrame:frame];
|
||
if (self) {
|
||
_showsReportAction = YES;
|
||
[self setupUI];
|
||
[self applyReportVisibility];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
#pragma mark - UI
|
||
|
||
- (void)setupUI {
|
||
self.backgroundColor = [UIColor colorWithWhite:0.1 alpha:0.92];
|
||
self.layer.cornerRadius = 16.0;
|
||
self.layer.masksToBounds = YES;
|
||
|
||
[self addSubview:self.copyRow];
|
||
[self addSubview:self.line1];
|
||
[self addSubview:self.deleteRow];
|
||
[self addSubview:self.line2];
|
||
[self addSubview:self.reportRow];
|
||
|
||
[self.copyRow mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.left.right.equalTo(self);
|
||
make.height.mas_equalTo(kKBChatActionRowHeight);
|
||
}];
|
||
|
||
[self.line1 mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(self.copyRow.mas_bottom);
|
||
make.left.right.equalTo(self);
|
||
make.height.mas_equalTo(0.5);
|
||
}];
|
||
|
||
[self.deleteRow mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(self.line1.mas_bottom);
|
||
make.left.right.equalTo(self);
|
||
make.height.mas_equalTo(kKBChatActionRowHeight);
|
||
}];
|
||
|
||
[self.line2 mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(self.deleteRow.mas_bottom);
|
||
make.left.right.equalTo(self);
|
||
make.height.mas_equalTo(0.5);
|
||
}];
|
||
|
||
[self.reportRow mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.top.equalTo(self.line2.mas_bottom);
|
||
make.left.right.bottom.equalTo(self);
|
||
make.height.mas_equalTo(kKBChatActionRowHeight);
|
||
}];
|
||
}
|
||
|
||
- (void)setShowsReportAction:(BOOL)showsReportAction {
|
||
if (_showsReportAction == showsReportAction) {
|
||
return;
|
||
}
|
||
_showsReportAction = showsReportAction;
|
||
[self applyReportVisibility];
|
||
}
|
||
|
||
- (void)applyReportVisibility {
|
||
BOOL show = self.showsReportAction;
|
||
self.reportRow.hidden = !show;
|
||
self.reportRow.userInteractionEnabled = show;
|
||
self.line2.hidden = !show;
|
||
|
||
// 通过约束把高度收起来,避免外部把 frame 调小后出现约束冲突
|
||
[self.line2 mas_updateConstraints:^(MASConstraintMaker *make) {
|
||
make.height.mas_equalTo(show ? 0.5 : 0.0);
|
||
}];
|
||
[self.reportRow mas_updateConstraints:^(MASConstraintMaker *make) {
|
||
make.height.mas_equalTo(show ? kKBChatActionRowHeight : 0.0);
|
||
}];
|
||
|
||
[self setNeedsLayout];
|
||
[self layoutIfNeeded];
|
||
}
|
||
|
||
- (UIControl *)buildRowWithTitle:(NSString *)title
|
||
iconName:(NSString *)iconName
|
||
action:(KBChatMessageActionType)action {
|
||
UIControl *row = [[UIControl alloc] init];
|
||
row.tag = action;
|
||
[row addTarget:self action:@selector(actionRowTapped:) forControlEvents:UIControlEventTouchUpInside];
|
||
|
||
UILabel *label = [[UILabel alloc] init];
|
||
label.text = title;
|
||
label.textColor = [UIColor whiteColor];
|
||
label.font = [UIFont systemFontOfSize:18 weight:UIFontWeightRegular];
|
||
|
||
UIImageView *iconView = [[UIImageView alloc] init];
|
||
UIImage *icon = [UIImage systemImageNamed:iconName];
|
||
iconView.image = icon;
|
||
iconView.tintColor = [UIColor whiteColor];
|
||
iconView.contentMode = UIViewContentModeScaleAspectFit;
|
||
|
||
[row addSubview:label];
|
||
[row addSubview:iconView];
|
||
|
||
[label mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.left.equalTo(row).offset(16);
|
||
make.centerY.equalTo(row);
|
||
}];
|
||
|
||
[iconView mas_makeConstraints:^(MASConstraintMaker *make) {
|
||
make.right.equalTo(row).offset(-16);
|
||
make.centerY.equalTo(row);
|
||
make.width.height.mas_equalTo(18);
|
||
}];
|
||
|
||
return row;
|
||
}
|
||
|
||
#pragma mark - Actions
|
||
|
||
- (void)actionRowTapped:(UIControl *)sender {
|
||
if ([self.delegate respondsToSelector:@selector(chatMessageActionPopView:didSelectAction:)]) {
|
||
[self.delegate chatMessageActionPopView:self didSelectAction:(KBChatMessageActionType)sender.tag];
|
||
}
|
||
}
|
||
|
||
#pragma mark - Lazy
|
||
|
||
- (UIControl *)copyRow {
|
||
if (!_copyRow) {
|
||
_copyRow = [self buildRowWithTitle:KBLocalized(@"Copy")
|
||
iconName:@"doc.on.doc"
|
||
action:KBChatMessageActionTypeCopy];
|
||
}
|
||
return _copyRow;
|
||
}
|
||
|
||
- (UIControl *)deleteRow {
|
||
if (!_deleteRow) {
|
||
_deleteRow = [self buildRowWithTitle:KBLocalized(@"Delete")
|
||
iconName:@"trash"
|
||
action:KBChatMessageActionTypeDelete];
|
||
}
|
||
return _deleteRow;
|
||
}
|
||
|
||
- (UIControl *)reportRow {
|
||
if (!_reportRow) {
|
||
_reportRow = [self buildRowWithTitle:KBLocalized(@"Report")
|
||
iconName:@"exclamationmark.circle"
|
||
action:KBChatMessageActionTypeReport];
|
||
}
|
||
return _reportRow;
|
||
}
|
||
|
||
- (UIView *)line1 {
|
||
if (!_line1) {
|
||
_line1 = [[UIView alloc] init];
|
||
_line1.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.12];
|
||
}
|
||
return _line1;
|
||
}
|
||
|
||
- (UIView *)line2 {
|
||
if (!_line2) {
|
||
_line2 = [[UIView alloc] init];
|
||
_line2.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.12];
|
||
}
|
||
return _line2;
|
||
}
|
||
|
||
@end
|