This commit is contained in:
2026-01-16 20:31:42 +08:00
parent 663cb8493b
commit 93489b09d9
6 changed files with 302 additions and 116 deletions

View File

@@ -43,29 +43,35 @@
} }
// Cell // Cell
// (68) + (28) + (8) + + (8) + (40) + (16) // (68) + (28) + (8) + + (50)
// = maxWidth - 68 - 28 - 8 - 8 - 40 - 16 // = maxWidth - 68 - 28 - 8 - 50
CGFloat contentWidth = maxWidth - 68 - 28 - 8 - 8 - 40 - 16; CGFloat contentWidth = maxWidth - 68 - 28 - 8 - 50;
// // "回复 @xxx"
NSMutableString *fullText = [NSMutableString stringWithString:self.userName]; NSMutableString *userNameText = [NSMutableString stringWithString:self.userName];
if (self.replyToUserName.length > 0) { if (self.replyToUserName.length > 0) {
[fullText appendFormat:@" 回复 @%@", self.replyToUserName]; [userNameText appendFormat:@" 回复 @%@", self.replyToUserName];
} }
[fullText appendFormat:@"%@", self.content]; UIFont *userNameFont = [UIFont systemFontOfSize:13 weight:UIFontWeightMedium];
CGRect userNameRect = [userNameText boundingRectWithSize:CGSizeMake(contentWidth, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName: userNameFont}
context:nil];
CGFloat userNameHeight = ceil(userNameRect.size.height);
//
UIFont *contentFont = [UIFont systemFontOfSize:14]; UIFont *contentFont = [UIFont systemFontOfSize:14];
CGRect contentRect = [fullText boundingRectWithSize:CGSizeMake(contentWidth, CGFLOAT_MAX) CGRect contentRect = [self.content boundingRectWithSize:CGSizeMake(contentWidth, CGFLOAT_MAX)
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName: contentFont} attributes:@{NSFontAttributeName: contentFont}
context:nil]; context:nil];
CGFloat contentHeight = ceil(contentRect.size.height); CGFloat contentHeight = ceil(contentRect.size.height);
// //
CGFloat timeHeight = 14; // 11 CGFloat timeHeight = 14; // 11
// = (8) + + (4) + + (8) // = (8) + + (4) + + (6) + + (8)
CGFloat totalHeight = 8 + contentHeight + 4 + timeHeight + 8; CGFloat totalHeight = 8 + userNameHeight + 4 + contentHeight + 6 + timeHeight + 8;
// + // +
CGFloat minHeight = 8 + 28 + 8; CGFloat minHeight = 8 + 28 + 8;

View File

@@ -20,6 +20,9 @@ NS_ASSUME_NONNULL_BEGIN
/// 点赞按钮点击回调 /// 点赞按钮点击回调
@property(nonatomic, copy, nullable) void (^onLikeAction)(void); @property(nonatomic, copy, nullable) void (^onLikeAction)(void);
/// 回复按钮点击回调
@property(nonatomic, copy, nullable) void (^onReplyAction)(void);
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -7,6 +7,7 @@
#import "KBAICommentHeaderView.h" #import "KBAICommentHeaderView.h"
#import "KBAICommentModel.h" #import "KBAICommentModel.h"
#import "KBTopImageButton.h"
#import <Masonry/Masonry.h> #import <Masonry/Masonry.h>
#import <SDWebImage/SDWebImage.h> #import <SDWebImage/SDWebImage.h>
@@ -14,9 +15,10 @@
@property(nonatomic, strong) UIImageView *avatarImageView; @property(nonatomic, strong) UIImageView *avatarImageView;
@property(nonatomic, strong) UILabel *userNameLabel; @property(nonatomic, strong) UILabel *userNameLabel;
@property(nonatomic, strong) UILabel *timeLabel;
@property(nonatomic, strong) UILabel *contentLabel; @property(nonatomic, strong) UILabel *contentLabel;
@property(nonatomic, strong) UIButton *likeButton; @property(nonatomic, strong) UILabel *timeLabel;
@property(nonatomic, strong) UIButton *replyButton;
@property(nonatomic, strong) KBTopImageButton *likeButton;
@end @end
@@ -37,8 +39,9 @@
[self.contentView addSubview:self.avatarImageView]; [self.contentView addSubview:self.avatarImageView];
[self.contentView addSubview:self.userNameLabel]; [self.contentView addSubview:self.userNameLabel];
[self.contentView addSubview:self.timeLabel];
[self.contentView addSubview:self.contentLabel]; [self.contentView addSubview:self.contentLabel];
[self.contentView addSubview:self.timeLabel];
[self.contentView addSubview:self.replyButton];
[self.contentView addSubview:self.likeButton]; [self.contentView addSubview:self.likeButton];
[self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) { [self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
@@ -53,24 +56,31 @@
make.right.lessThanOrEqualTo(self.likeButton.mas_left).offset(-10); make.right.lessThanOrEqualTo(self.likeButton.mas_left).offset(-10);
}]; }];
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.userNameLabel); make.left.equalTo(self.userNameLabel);
make.top.equalTo(self.userNameLabel.mas_bottom).offset(2); make.top.equalTo(self.contentLabel.mas_bottom).offset(8);
make.bottom.equalTo(self.contentView).offset(-12).priority(MASLayoutPriorityDefaultHigh);
}]; }];
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.replyButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.userNameLabel); make.left.equalTo(self.timeLabel.mas_right).offset(16);
make.top.equalTo(self.timeLabel.mas_bottom).offset(8); make.centerY.equalTo(self.timeLabel);
make.right.equalTo(self.contentView).offset(-50);
make.bottom.equalTo(self.contentView).offset(-12).priority(MASLayoutPriorityDefaultHigh);
}]; }];
[self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) { [self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.contentView).offset(-16); make.right.equalTo(self.contentView).offset(-16);
make.top.equalTo(self.contentView).offset(12); make.top.equalTo(self.contentView).offset(12);
make.width.mas_equalTo(50); make.width.mas_equalTo(30);
make.height.mas_equalTo(40); make.height.mas_equalTo(40);
}]; }];
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.userNameLabel);
make.top.equalTo(self.userNameLabel.mas_bottom).offset(6);
make.right.equalTo(self.likeButton.mas_left).offset(-5);
}];
} }
#pragma mark - Configuration #pragma mark - Configuration
@@ -80,19 +90,19 @@
sd_setImageWithURL:[NSURL URLWithString:comment.avatarUrl] sd_setImageWithURL:[NSURL URLWithString:comment.avatarUrl]
placeholderImage:[UIImage imageNamed:@"default_avatar"]]; placeholderImage:[UIImage imageNamed:@"default_avatar"]];
self.userNameLabel.text = comment.userName; self.userNameLabel.text = comment.userName;
self.timeLabel.text = [comment formattedTime];
self.contentLabel.text = comment.content; self.contentLabel.text = comment.content;
self.timeLabel.text = [comment formattedTime];
// //
NSString *likeText = NSString *likeText =
comment.likeCount > 0 ? [self formatLikeCount:comment.likeCount] : @"赞"; comment.likeCount > 0 ? [self formatLikeCount:comment.likeCount] : @"赞";
[self.likeButton setTitle:likeText forState:UIControlStateNormal]; self.likeButton.textLabel.text = likeText;
UIImage *likeImage = comment.isLiked UIImage *likeImage = comment.isLiked
? [UIImage systemImageNamed:@"heart.fill"] ? [UIImage systemImageNamed:@"heart.fill"]
: [UIImage systemImageNamed:@"heart"]; : [UIImage systemImageNamed:@"heart"];
[self.likeButton setImage:likeImage forState:UIControlStateNormal]; self.likeButton.iconView.image = likeImage;
self.likeButton.tintColor = self.likeButton.iconView.tintColor =
comment.isLiked ? [UIColor systemRedColor] : [UIColor grayColor]; comment.isLiked ? [UIColor systemRedColor] : [UIColor grayColor];
} }
@@ -113,6 +123,12 @@
} }
} }
- (void)replyButtonTapped {
if (self.onReplyAction) {
self.onReplyAction();
}
}
#pragma mark - Lazy Loading #pragma mark - Lazy Loading
- (UIImageView *)avatarImageView { - (UIImageView *)avatarImageView {
@@ -129,22 +145,12 @@
- (UILabel *)userNameLabel { - (UILabel *)userNameLabel {
if (!_userNameLabel) { if (!_userNameLabel) {
_userNameLabel = [[UILabel alloc] init]; _userNameLabel = [[UILabel alloc] init];
_userNameLabel.font = [UIFont systemFontOfSize:14 _userNameLabel.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
weight:UIFontWeightMedium]; _userNameLabel.textColor = [UIColor secondaryLabelColor];
_userNameLabel.textColor = [UIColor labelColor];
} }
return _userNameLabel; return _userNameLabel;
} }
- (UILabel *)timeLabel {
if (!_timeLabel) {
_timeLabel = [[UILabel alloc] init];
_timeLabel.font = [UIFont systemFontOfSize:12];
_timeLabel.textColor = [UIColor secondaryLabelColor];
}
return _timeLabel;
}
- (UILabel *)contentLabel { - (UILabel *)contentLabel {
if (!_contentLabel) { if (!_contentLabel) {
_contentLabel = [[UILabel alloc] init]; _contentLabel = [[UILabel alloc] init];
@@ -155,19 +161,37 @@
return _contentLabel; return _contentLabel;
} }
- (UIButton *)likeButton { - (UILabel *)timeLabel {
if (!_likeButton) { if (!_timeLabel) {
_likeButton = [UIButton buttonWithType:UIButtonTypeCustom]; _timeLabel = [[UILabel alloc] init];
_likeButton.titleLabel.font = [UIFont systemFontOfSize:12]; _timeLabel.font = [UIFont systemFontOfSize:12];
[_likeButton setTitleColor:[UIColor grayColor] _timeLabel.textColor = [UIColor secondaryLabelColor];
forState:UIControlStateNormal]; }
[_likeButton setImage:[UIImage systemImageNamed:@"heart"] return _timeLabel;
forState:UIControlStateNormal]; }
_likeButton.tintColor = [UIColor grayColor];
// - (UIButton *)replyButton {
_likeButton.contentHorizontalAlignment = if (!_replyButton) {
UIControlContentHorizontalAlignmentCenter; _replyButton = [UIButton buttonWithType:UIButtonTypeCustom];
_replyButton.titleLabel.font = [UIFont systemFontOfSize:12];
[_replyButton setTitle:@"回复" forState:UIControlStateNormal];
[_replyButton setTitleColor:[UIColor secondaryLabelColor] forState:UIControlStateNormal];
[_replyButton addTarget:self
action:@selector(replyButtonTapped)
forControlEvents:UIControlEventTouchUpInside];
}
return _replyButton;
}
- (KBTopImageButton *)likeButton {
if (!_likeButton) {
_likeButton = [[KBTopImageButton alloc] init];
_likeButton.iconSize = CGSizeMake(20, 20);
_likeButton.spacing = 2;
_likeButton.iconView.image = [UIImage systemImageNamed:@"heart"];
_likeButton.iconView.tintColor = [UIColor grayColor];
_likeButton.textLabel.font = [UIFont systemFontOfSize:11];
_likeButton.textLabel.textColor = [UIColor grayColor];
[_likeButton addTarget:self [_likeButton addTarget:self
action:@selector(likeButtonTapped) action:@selector(likeButtonTapped)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];

View File

@@ -35,6 +35,11 @@ static NSString *const kCommentFooterIdentifier = @"CommentFooter";
/// ///
@property(nonatomic, strong) MASConstraint *inputBottomConstraint; @property(nonatomic, strong) MASConstraint *inputBottomConstraint;
///
@property(nonatomic, weak) KBAICommentModel *replyToComment;
///
@property(nonatomic, weak) KBAIReplyModel *replyToReply;
@end @end
@implementation KBAICommentView @implementation KBAICommentView
@@ -245,6 +250,10 @@ static NSString *const kCommentFooterIdentifier = @"CommentFooter";
[weakSelf.tableView reloadRowsAtIndexPaths:@[ indexPath ] [weakSelf.tableView reloadRowsAtIndexPaths:@[ indexPath ]
withRowAnimation:UITableViewRowAnimationNone]; withRowAnimation:UITableViewRowAnimationNone];
}; };
cell.onReplyAction = ^{
[weakSelf setReplyToComment:comment reply:reply];
};
return cell; return cell;
} }
@@ -267,6 +276,10 @@ static NSString *const kCommentFooterIdentifier = @"CommentFooter";
[weakSelf.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] [weakSelf.tableView reloadSections:[NSIndexSet indexSetWithIndex:section]
withRowAnimation:UITableViewRowAnimationNone]; withRowAnimation:UITableViewRowAnimationNone];
}; };
header.onReplyAction = ^{
[weakSelf setReplyToComment:comment reply:nil];
};
return header; return header;
} }
@@ -481,12 +494,55 @@ static NSInteger const kRepliesLoadCount = 5;
return _inputView; return _inputView;
} }
#pragma mark - Reply
- (void)setReplyToComment:(KBAICommentModel *)comment reply:(KBAIReplyModel *)reply {
self.replyToComment = comment;
self.replyToReply = reply;
if (reply) {
//
self.inputView.placeholder = [NSString stringWithFormat:@"回复 @%@", reply.userName];
} else if (comment) {
//
self.inputView.placeholder = [NSString stringWithFormat:@"回复 @%@", comment.userName];
} else {
//
self.inputView.placeholder = @"说点什么...";
}
}
- (void)clearReplyTarget {
self.replyToComment = nil;
self.replyToReply = nil;
self.inputView.placeholder = @"说点什么...";
}
#pragma mark - Send Comment #pragma mark - Send Comment
- (void)sendCommentWithText:(NSString *)text { - (void)sendCommentWithText:(NSString *)text {
if (text.length == 0) return; if (text.length == 0) return;
// CGFloat tableWidth = self.tableView.bounds.size.width;
if (tableWidth <= 0) {
tableWidth = [UIScreen mainScreen].bounds.size.width;
}
if (self.replyToComment) {
//
[self sendReplyWithText:text tableWidth:tableWidth];
} else {
//
[self sendNewCommentWithText:text tableWidth:tableWidth];
}
//
[self.inputView clearText];
[self clearReplyTarget];
}
- (void)sendNewCommentWithText:(NSString *)text tableWidth:(CGFloat)tableWidth {
//
KBAICommentModel *newComment = [[KBAICommentModel alloc] init]; KBAICommentModel *newComment = [[KBAICommentModel alloc] init];
newComment.commentId = [NSUUID UUID].UUIDString; newComment.commentId = [NSUUID UUID].UUIDString;
newComment.userId = @"current_user"; newComment.userId = @"current_user";
@@ -499,10 +555,6 @@ static NSInteger const kRepliesLoadCount = 5;
newComment.replies = @[]; newComment.replies = @[];
// //
CGFloat tableWidth = self.tableView.bounds.size.width;
if (tableWidth <= 0) {
tableWidth = [UIScreen mainScreen].bounds.size.width;
}
newComment.cachedHeaderHeight = [newComment calculateHeaderHeightWithMaxWidth:tableWidth]; newComment.cachedHeaderHeight = [newComment calculateHeaderHeightWithMaxWidth:tableWidth];
// //
@@ -516,9 +568,69 @@ static NSInteger const kRepliesLoadCount = 5;
// //
[self.tableView setContentOffset:CGPointZero animated:YES]; [self.tableView setContentOffset:CGPointZero animated:YES];
}
- (void)sendReplyWithText:(NSString *)text tableWidth:(CGFloat)tableWidth {
KBAICommentModel *comment = self.replyToComment;
if (!comment) return;
// //
[self.inputView clearText]; KBAIReplyModel *newReply = [[KBAIReplyModel alloc] init];
newReply.replyId = [NSUUID UUID].UUIDString;
newReply.userId = @"current_user";
newReply.userName = @"我";
newReply.avatarUrl = @"";
newReply.content = text;
newReply.likeCount = 0;
newReply.isLiked = NO;
newReply.createTime = [[NSDate date] timeIntervalSince1970];
//
if (self.replyToReply) {
newReply.replyToUserName = self.replyToReply.userName;
}
//
newReply.cachedCellHeight = [newReply calculateCellHeightWithMaxWidth:tableWidth];
// replies
NSMutableArray *newReplies = [NSMutableArray arrayWithArray:comment.replies];
[newReplies addObject:newReply];
comment.replies = newReplies;
comment.totalReplyCount = newReplies.count;
// section
NSInteger section = [self.comments indexOfObject:comment];
if (section == NSNotFound) return;
// displayedReplies
if (comment.isRepliesExpanded) {
NSInteger newRowIndex = comment.displayedReplies.count;
[comment.displayedReplies addObject:newReply];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:section];
[self.tableView insertRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
// Footer
KBAICommentFooterView *footerView =
(KBAICommentFooterView *)[self.tableView footerViewForSection:section];
if (footerView) {
[footerView configureWithComment:comment];
}
//
[self.tableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionBottom
animated:YES];
} else {
// Footer
KBAICommentFooterView *footerView =
(KBAICommentFooterView *)[self.tableView footerViewForSection:section];
if (footerView) {
[footerView configureWithComment:comment];
}
}
} }
@end @end

View File

@@ -20,6 +20,9 @@ NS_ASSUME_NONNULL_BEGIN
/// 点赞按钮点击回调 /// 点赞按钮点击回调
@property(nonatomic, copy, nullable) void (^onLikeAction)(void); @property(nonatomic, copy, nullable) void (^onLikeAction)(void);
/// 回复按钮点击回调
@property(nonatomic, copy, nullable) void (^onReplyAction)(void);
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@@ -7,15 +7,18 @@
#import "KBAIReplyCell.h" #import "KBAIReplyCell.h"
#import "KBAIReplyModel.h" #import "KBAIReplyModel.h"
#import "KBTopImageButton.h"
#import <Masonry/Masonry.h> #import <Masonry/Masonry.h>
#import <SDWebImage/SDWebImage.h> #import <SDWebImage/SDWebImage.h>
@interface KBAIReplyCell () @interface KBAIReplyCell ()
@property(nonatomic, strong) UIImageView *avatarImageView; @property(nonatomic, strong) UIImageView *avatarImageView;
@property(nonatomic, strong) UILabel *userNameLabel;
@property(nonatomic, strong) UILabel *contentLabel; @property(nonatomic, strong) UILabel *contentLabel;
@property(nonatomic, strong) UILabel *timeLabel; @property(nonatomic, strong) UILabel *timeLabel;
@property(nonatomic, strong) UIButton *likeButton; @property(nonatomic, strong) UIButton *replyButton;
@property(nonatomic, strong) KBTopImageButton *likeButton;
@end @end
@@ -36,36 +39,48 @@
- (void)setupUI { - (void)setupUI {
[self.contentView addSubview:self.avatarImageView]; [self.contentView addSubview:self.avatarImageView];
[self.contentView addSubview:self.userNameLabel];
[self.contentView addSubview:self.contentLabel]; [self.contentView addSubview:self.contentLabel];
[self.contentView addSubview:self.timeLabel]; [self.contentView addSubview:self.timeLabel];
[self.contentView addSubview:self.replyButton];
[self.contentView addSubview:self.likeButton]; [self.contentView addSubview:self.likeButton];
// 48pt //
[self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) { [self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.contentView).offset(68); // 16 + 40 + 12 = 68 make.left.equalTo(self.contentView).offset(68); // 16 + 40 + 12 = 68
make.top.equalTo(self.contentView).offset(8); make.top.equalTo(self.contentView).offset(8);
make.width.height.mas_equalTo(28); make.width.height.mas_equalTo(28);
}]; }];
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.userNameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.avatarImageView.mas_right).offset(8); make.left.equalTo(self.avatarImageView.mas_right).offset(8);
make.top.equalTo(self.avatarImageView); make.top.equalTo(self.avatarImageView);
make.right.equalTo(self.likeButton.mas_left).offset(-8); make.right.equalTo(self.contentView).offset(-50);
}]; }];
[self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) { [self.timeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.contentLabel); make.left.equalTo(self.userNameLabel);
make.top.equalTo(self.contentLabel.mas_bottom).offset(4); make.top.equalTo(self.contentLabel.mas_bottom).offset(6);
// TableView
make.bottom.equalTo(self.contentView).offset(-8).priority(MASLayoutPriorityDefaultHigh); make.bottom.equalTo(self.contentView).offset(-8).priority(MASLayoutPriorityDefaultHigh);
}]; }];
[self.replyButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.timeLabel.mas_right).offset(16);
make.centerY.equalTo(self.timeLabel);
}];
[self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) { [self.likeButton mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.contentView).offset(-16); make.right.equalTo(self.contentView).offset(-16);
make.top.equalTo(self.contentView).offset(8); make.top.equalTo(self.contentView).offset(8);
make.width.mas_equalTo(40); make.width.mas_equalTo(30);
make.height.mas_equalTo(30); make.height.mas_equalTo(30);
}]; }];
[self.contentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.userNameLabel);
make.top.equalTo(self.userNameLabel.mas_bottom).offset(4);
make.right.equalTo(self.likeButton.mas_left).offset(-5);
}];
} }
#pragma mark - Configuration #pragma mark - Configuration
@@ -75,58 +90,54 @@
sd_setImageWithURL:[NSURL URLWithString:reply.avatarUrl] sd_setImageWithURL:[NSURL URLWithString:reply.avatarUrl]
placeholderImage:[UIImage imageNamed:@"default_avatar"]]; placeholderImage:[UIImage imageNamed:@"default_avatar"]];
// + @+ // "用户名 回复 @被回复用户"
NSMutableAttributedString *attrText =
[[NSMutableAttributedString alloc] init];
//
NSDictionary *nameAttrs = @{
NSFontAttributeName : [UIFont systemFontOfSize:14
weight:UIFontWeightMedium],
NSForegroundColorAttributeName : [UIColor labelColor]
};
[attrText appendAttributedString:[[NSAttributedString alloc]
initWithString:reply.userName
attributes:nameAttrs]];
// @
if (reply.replyToUserName.length > 0) { if (reply.replyToUserName.length > 0) {
NSMutableAttributedString *attrName = [[NSMutableAttributedString alloc] init];
NSDictionary *nameAttrs = @{
NSFontAttributeName : [UIFont systemFontOfSize:13 weight:UIFontWeightMedium],
NSForegroundColorAttributeName : [UIColor secondaryLabelColor]
};
[attrName appendAttributedString:[[NSAttributedString alloc]
initWithString:reply.userName
attributes:nameAttrs]];
NSDictionary *replyAttrs = @{ NSDictionary *replyAttrs = @{
NSFontAttributeName : [UIFont systemFontOfSize:14], NSFontAttributeName : [UIFont systemFontOfSize:13],
NSForegroundColorAttributeName : [UIColor secondaryLabelColor]
};
[attrName appendAttributedString:[[NSAttributedString alloc]
initWithString:@" 回复 "
attributes:replyAttrs]];
NSDictionary *toUserAttrs = @{
NSFontAttributeName : [UIFont systemFontOfSize:13],
NSForegroundColorAttributeName : [UIColor systemBlueColor] NSForegroundColorAttributeName : [UIColor systemBlueColor]
}; };
NSString *replyTo = [attrName appendAttributedString:[[NSAttributedString alloc]
[NSString stringWithFormat:@" 回复 @%@", reply.replyToUserName]; initWithString:[NSString stringWithFormat:@"@%@", reply.replyToUserName]
[attrText appendAttributedString:[[NSAttributedString alloc] attributes:toUserAttrs]];
initWithString:replyTo
attributes:replyAttrs]]; self.userNameLabel.attributedText = attrName;
} else {
self.userNameLabel.attributedText = nil;
self.userNameLabel.text = reply.userName;
} }
// //
NSDictionary *contentAttrs = @{ self.contentLabel.text = reply.content;
NSFontAttributeName : [UIFont systemFontOfSize:14],
NSForegroundColorAttributeName : [UIColor labelColor]
};
NSString *content = [NSString stringWithFormat:@"%@", reply.content];
[attrText appendAttributedString:[[NSAttributedString alloc]
initWithString:content
attributes:contentAttrs]];
self.contentLabel.attributedText = attrText;
// //
self.timeLabel.text = [reply formattedTime]; self.timeLabel.text = [reply formattedTime];
// //
NSString *likeText = NSString *likeText = reply.likeCount > 0 ? [self formatLikeCount:reply.likeCount] : @"";
reply.likeCount > 0 ? [self formatLikeCount:reply.likeCount] : @""; self.likeButton.textLabel.text = likeText;
[self.likeButton setTitle:likeText forState:UIControlStateNormal];
UIImage *likeImage = reply.isLiked ? [UIImage systemImageNamed:@"heart.fill"] UIImage *likeImage = reply.isLiked ? [UIImage systemImageNamed:@"heart.fill"]
: [UIImage systemImageNamed:@"heart"]; : [UIImage systemImageNamed:@"heart"];
[self.likeButton setImage:likeImage forState:UIControlStateNormal]; self.likeButton.iconView.image = likeImage;
self.likeButton.tintColor = self.likeButton.iconView.tintColor = reply.isLiked ? [UIColor systemRedColor] : [UIColor grayColor];
reply.isLiked ? [UIColor systemRedColor] : [UIColor grayColor];
} }
- (NSString *)formatLikeCount:(NSInteger)count { - (NSString *)formatLikeCount:(NSInteger)count {
@@ -146,6 +157,12 @@
} }
} }
- (void)replyButtonTapped {
if (self.onReplyAction) {
self.onReplyAction();
}
}
#pragma mark - Lazy Loading #pragma mark - Lazy Loading
- (UIImageView *)avatarImageView { - (UIImageView *)avatarImageView {
@@ -159,9 +176,21 @@
return _avatarImageView; return _avatarImageView;
} }
- (UILabel *)userNameLabel {
if (!_userNameLabel) {
_userNameLabel = [[UILabel alloc] init];
_userNameLabel.font = [UIFont systemFontOfSize:13 weight:UIFontWeightMedium];
_userNameLabel.textColor = [UIColor secondaryLabelColor];
_userNameLabel.numberOfLines = 0;
}
return _userNameLabel;
}
- (UILabel *)contentLabel { - (UILabel *)contentLabel {
if (!_contentLabel) { if (!_contentLabel) {
_contentLabel = [[UILabel alloc] init]; _contentLabel = [[UILabel alloc] init];
_contentLabel.font = [UIFont systemFontOfSize:14];
_contentLabel.textColor = [UIColor labelColor];
_contentLabel.numberOfLines = 0; _contentLabel.numberOfLines = 0;
} }
return _contentLabel; return _contentLabel;
@@ -176,22 +205,31 @@
return _timeLabel; return _timeLabel;
} }
- (UIButton *)likeButton { - (UIButton *)replyButton {
if (!_replyButton) {
_replyButton = [UIButton buttonWithType:UIButtonTypeCustom];
_replyButton.titleLabel.font = [UIFont systemFontOfSize:11];
[_replyButton setTitle:@"回复" forState:UIControlStateNormal];
[_replyButton setTitleColor:[UIColor secondaryLabelColor] forState:UIControlStateNormal];
[_replyButton addTarget:self
action:@selector(replyButtonTapped)
forControlEvents:UIControlEventTouchUpInside];
}
return _replyButton;
}
- (KBTopImageButton *)likeButton {
if (!_likeButton) { if (!_likeButton) {
_likeButton = [UIButton buttonWithType:UIButtonTypeCustom]; _likeButton = [[KBTopImageButton alloc] init];
_likeButton.titleLabel.font = [UIFont systemFontOfSize:11]; _likeButton.iconSize = CGSizeMake(16, 16);
[_likeButton setTitleColor:[UIColor grayColor] _likeButton.spacing = 2;
forState:UIControlStateNormal]; _likeButton.iconView.image = [UIImage systemImageNamed:@"heart"];
[_likeButton setImage:[UIImage systemImageNamed:@"heart"] _likeButton.iconView.tintColor = [UIColor grayColor];
forState:UIControlStateNormal]; _likeButton.textLabel.font = [UIFont systemFontOfSize:10];
_likeButton.tintColor = [UIColor grayColor]; _likeButton.textLabel.textColor = [UIColor grayColor];
[_likeButton addTarget:self [_likeButton addTarget:self
action:@selector(likeButtonTapped) action:@selector(likeButtonTapped)
forControlEvents:UIControlEventTouchUpInside]; forControlEvents:UIControlEventTouchUpInside];
//
_likeButton.imageEdgeInsets = UIEdgeInsetsMake(0, -2, 0, 2);
_likeButton.titleEdgeInsets = UIEdgeInsetsMake(0, 2, 0, -2);
} }
return _likeButton; return _likeButton;
} }