增加换肤功能
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
/**
|
||||
* This document declares that after the group is successfully created, the "xxx create group chat" message cell displayed when jumping to the message
|
||||
* interface
|
||||
*/
|
||||
|
||||
#import <TIMCommon/TUISystemMessageCell.h>
|
||||
#import "TUIGroupCreatedCellData.h"
|
||||
|
||||
@interface TUIGroupCreatedCell_Minimalist : TUISystemMessageCell
|
||||
|
||||
- (void)fillWithData:(TUIGroupCreatedCellData *)data;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// MyCustomCell.m
|
||||
// TUIKitDemo
|
||||
//
|
||||
// Created by annidyfeng on 2019/6/10.
|
||||
// Copyright © 2019 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIGroupCreatedCell_Minimalist.h"
|
||||
|
||||
@implementation TUIGroupCreatedCell_Minimalist
|
||||
|
||||
- (void)fillWithData:(TUIGroupCreatedCellData *)data {
|
||||
[super fillWithData:data];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,20 @@
|
||||
//
|
||||
// TUIGroupProfileCardCellData.h
|
||||
// TUIGroup
|
||||
//
|
||||
// Created by wyl on 2023/1/3.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
@class UINavigationController;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TUIGroupProfileCardCellData_Minimalist : TUIProfileCardCellData
|
||||
|
||||
@property(nonatomic, weak) UINavigationController *navigationController;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// TUIGroupProfileCardCellData_Minimalist.m
|
||||
// TUIGroup
|
||||
//
|
||||
// Created by wyl on 2023/1/3.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIGroupProfileCardCellData_Minimalist.h"
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import <TUICore/TUIThemeManager.h>
|
||||
|
||||
@implementation TUIGroupProfileCardCellData_Minimalist
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGFloat)heightOfWidth:(CGFloat)width {
|
||||
return kScale390(329);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// TUIGroupProfileCardViewCell_Minimalist.h
|
||||
// TUIGroup
|
||||
//
|
||||
// Created by wyl on 2023/1/3.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
#import "TUIGroupProfileCardCellData_Minimalist.h"
|
||||
|
||||
@class V2TIMGroupInfo;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface TUIGroupProfileHeaderItemView_Minimalist : UIView
|
||||
@property(nonatomic, strong) UIImageView *iconView;
|
||||
@property(nonatomic, strong) UILabel *textLabel;
|
||||
@property(nonatomic, copy) void (^messageBtnClickBlock)(void);
|
||||
@end
|
||||
|
||||
@interface TUIGroupProfileHeaderView_Minimalist : UIView
|
||||
@property(nonatomic, strong) UIImageView *headImg;
|
||||
@property(nonatomic, copy) void (^headImgClickBlock)(void);
|
||||
@property(nonatomic, strong) UILabel *descriptionLabel;
|
||||
@property(nonatomic, strong) UIButton *editButton;
|
||||
@property(nonatomic, copy) void (^editBtnClickBlock)(void);
|
||||
@property(nonatomic, strong) UILabel *idLabel;
|
||||
@property(nonatomic, strong) UIView *functionListView;
|
||||
@property(nonatomic, strong) NSArray<TUIGroupProfileHeaderItemView_Minimalist *> *itemViewList;
|
||||
@property(nonatomic, strong) V2TIMGroupInfo *groupInfo;
|
||||
|
||||
@end
|
||||
|
||||
@interface TUIGroupProfileCardViewCell_Minimalist : TUICommonTableViewCell
|
||||
@property(nonatomic, strong) TUIGroupProfileHeaderView_Minimalist *headerView;
|
||||
@property(nonatomic, strong) TUIGroupProfileCardCellData_Minimalist *cardData;
|
||||
- (void)fillWithData:(TUIGroupProfileCardCellData_Minimalist *)data;
|
||||
|
||||
@property(nonatomic, strong) NSArray<TUIGroupProfileHeaderItemView_Minimalist *> *itemViewList;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,304 @@
|
||||
//
|
||||
// TUIGroupProfileCardViewCell.m
|
||||
// TUIGroup
|
||||
//
|
||||
// Created by wyl on 2023/1/3.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIGroupProfileCardViewCell_Minimalist.h"
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import <TIMCommon/TUIGroupAvatar+Helper.h>
|
||||
#import <TUICore/TUICore.h>
|
||||
#import <TUICore/TUIThemeManager.h>
|
||||
|
||||
@implementation TUIGroupProfileHeaderItemView_Minimalist
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self setupView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (void)setupView {
|
||||
self.iconView = [[UIImageView alloc] initWithImage:DefaultAvatarImage];
|
||||
[self addSubview:self.iconView];
|
||||
self.iconView.userInteractionEnabled = YES;
|
||||
self.iconView.contentMode = UIViewContentModeScaleAspectFit;
|
||||
|
||||
self.textLabel = [[UILabel alloc] init];
|
||||
self.textLabel.font = [UIFont systemFontOfSize:kScale390(16)];
|
||||
self.textLabel.rtlAlignment = TUITextRTLAlignmentCenter;
|
||||
self.textLabel.textColor = [UIColor tui_colorWithHex:@"#000000"];
|
||||
self.textLabel.userInteractionEnabled = YES;
|
||||
[self addSubview:self.textLabel];
|
||||
self.textLabel.text = @"Message";
|
||||
|
||||
self.backgroundColor = [UIColor tui_colorWithHex:@"#f9f9f9"];
|
||||
self.layer.cornerRadius = kScale390(12);
|
||||
self.layer.masksToBounds = YES;
|
||||
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(click)];
|
||||
[self addGestureRecognizer:tap];
|
||||
}
|
||||
+ (BOOL)requiresConstraintBasedLayout {
|
||||
return YES;
|
||||
}
|
||||
|
||||
// this is Apple's recommended place for adding/updating constraints
|
||||
- (void)updateConstraints {
|
||||
|
||||
[super updateConstraints];
|
||||
[self.iconView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.height.mas_equalTo(kScale390(30));
|
||||
make.top.mas_equalTo(kScale390(19));
|
||||
make.centerX.mas_equalTo(self);
|
||||
}];
|
||||
[self.textLabel sizeToFit];
|
||||
[self.textLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.trailing.mas_equalTo(self);
|
||||
make.height.mas_equalTo(kScale390(19));
|
||||
make.top.mas_equalTo(self.iconView.mas_bottom).mas_offset(kScale390(11));
|
||||
make.centerX.mas_equalTo(self);
|
||||
}];
|
||||
}
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
|
||||
}
|
||||
- (void)click {
|
||||
if (self.messageBtnClickBlock) {
|
||||
self.messageBtnClickBlock();
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@interface TUIGroupProfileHeaderView_Minimalist ()
|
||||
@end
|
||||
|
||||
@implementation TUIGroupProfileHeaderView_Minimalist
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self setupView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setupView {
|
||||
self.headImg = [[UIImageView alloc] initWithImage:DefaultAvatarImage];
|
||||
[self addSubview:self.headImg];
|
||||
self.headImg.userInteractionEnabled = YES;
|
||||
self.headImg.contentMode = UIViewContentModeScaleAspectFit;
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(headImageClick)];
|
||||
[self.headImg addGestureRecognizer:tap];
|
||||
|
||||
self.descriptionLabel = [[UILabel alloc] init];
|
||||
self.descriptionLabel.font = [UIFont boldSystemFontOfSize:kScale390(24)];
|
||||
self.descriptionLabel.textAlignment = NSTextAlignmentCenter;
|
||||
self.descriptionLabel.userInteractionEnabled = YES;
|
||||
[self addSubview:self.descriptionLabel];
|
||||
|
||||
self.editButton = [UIButton buttonWithType:UIButtonTypeSystem];
|
||||
[self addSubview:self.editButton];
|
||||
[self.editButton setImage:[UIImage imageNamed:TUIContactImagePath(@"icon_group_edit")] forState:UIControlStateNormal];
|
||||
[self.editButton addTarget:self action:@selector(editButtonClick) forControlEvents:UIControlEventTouchUpInside];
|
||||
self.editButton.hidden = YES;
|
||||
|
||||
self.idLabel = [[UILabel alloc] init];
|
||||
self.idLabel.font = [UIFont systemFontOfSize:kScale390(12)];
|
||||
self.idLabel.textColor = [UIColor tui_colorWithHex:@"666666"];
|
||||
self.idLabel.textAlignment = NSTextAlignmentCenter;
|
||||
self.idLabel.userInteractionEnabled = YES;
|
||||
[self addSubview:self.idLabel];
|
||||
|
||||
self.functionListView = [[UIView alloc] init];
|
||||
self.functionListView.userInteractionEnabled = YES;
|
||||
[self addSubview:self.functionListView];
|
||||
}
|
||||
|
||||
- (void)setGroupInfo:(V2TIMGroupInfo *)groupInfo {
|
||||
_groupInfo = groupInfo;
|
||||
[self.headImg sd_setImageWithURL:[NSURL URLWithString:self.groupInfo.faceURL]
|
||||
placeholderImage:DefaultGroupAvatarImageByGroupType(self.groupInfo.groupType)];
|
||||
[self configHeadImageView:groupInfo];
|
||||
|
||||
self.descriptionLabel.text = groupInfo.groupName;
|
||||
self.idLabel.text = self.groupInfo.groupID;
|
||||
if ([self.class isMeSuper:groupInfo]) {
|
||||
self.editButton.hidden = NO;
|
||||
}
|
||||
|
||||
// tell constraints they need updating
|
||||
[self setNeedsUpdateConstraints];
|
||||
|
||||
// update constraints now so we can animate the change
|
||||
[self updateConstraintsIfNeeded];
|
||||
|
||||
[self layoutIfNeeded];
|
||||
|
||||
}
|
||||
- (void)configHeadImageView:(V2TIMGroupInfo *)groupInfo {
|
||||
/**
|
||||
* Setup default avatar
|
||||
*/
|
||||
if (groupInfo.groupID.length > 0) {
|
||||
/**
|
||||
* If it is a group, change the group default avatar to the last used avatar
|
||||
*/
|
||||
[self.headImg sd_setImageWithURL:[NSURL URLWithString:self.groupInfo.faceURL]
|
||||
placeholderImage:DefaultGroupAvatarImageByGroupType(self.groupInfo.groupType)];
|
||||
}
|
||||
|
||||
@weakify(self);
|
||||
NSString *groupID = groupInfo.groupID ?: @"";
|
||||
NSString *pFaceUrl = groupInfo.faceURL ?: @"";
|
||||
NSString *groupType = groupInfo.groupType ?: @"";
|
||||
UIImage *originAvatarImage = DefaultGroupAvatarImageByGroupType(self.groupInfo.groupType) ?: [UIImage new];
|
||||
|
||||
NSDictionary *param = @{
|
||||
@"groupID" : groupID,
|
||||
@"faceUrl" : pFaceUrl,
|
||||
@"groupType" : groupType,
|
||||
@"originAvatarImage" : originAvatarImage,
|
||||
};
|
||||
[TUIGroupAvatar configAvatarByParam:param targetView:self.headImg];
|
||||
}
|
||||
|
||||
- (void)setItemViewList:(NSArray<TUIGroupProfileHeaderItemView_Minimalist *> *)itemList {
|
||||
for (UIView *subView in self.functionListView.subviews) {
|
||||
[subView removeFromSuperview];
|
||||
}
|
||||
if (itemList.count > 0) {
|
||||
for (TUIGroupProfileHeaderItemView_Minimalist *itemView in itemList) {
|
||||
[self.functionListView addSubview:itemView];
|
||||
}
|
||||
CGFloat width = kScale390(92);
|
||||
CGFloat height = kScale390(95);
|
||||
CGFloat space = kScale390(18);
|
||||
CGFloat contentWidth = itemList.count * width + (itemList.count - 1) * space;
|
||||
CGFloat x = 0.5 * (self.bounds.size.width - contentWidth);
|
||||
for (TUIGroupProfileHeaderItemView_Minimalist *itemView in itemList) {
|
||||
itemView.frame = CGRectMake(x, 0, width, height);
|
||||
x = CGRectGetMaxX(itemView.frame) + space;
|
||||
}
|
||||
}
|
||||
}
|
||||
+ (BOOL)requiresConstraintBasedLayout {
|
||||
return YES;
|
||||
}
|
||||
|
||||
// this is Apple's recommended place for adding/updating constraints
|
||||
- (void)updateConstraints {
|
||||
|
||||
[super updateConstraints];
|
||||
CGFloat imgWidth = kScale390(94);
|
||||
[self.headImg mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.height.mas_equalTo(imgWidth);
|
||||
make.centerX.mas_equalTo(self.mas_centerX);
|
||||
make.top.mas_equalTo(kScale390(42));
|
||||
}];
|
||||
|
||||
MASAttachKeys(self.headImg);
|
||||
|
||||
if ([TUIConfig defaultConfig].avatarType == TAvatarTypeRounded) {
|
||||
self.headImg.layer.masksToBounds = YES;
|
||||
self.headImg.layer.cornerRadius = imgWidth / 2;
|
||||
} else if ([TUIConfig defaultConfig].avatarType == TAvatarTypeRadiusCorner) {
|
||||
self.headImg.layer.masksToBounds = YES;
|
||||
self.headImg.layer.cornerRadius = [TUIConfig defaultConfig].avatarCornerRadius;
|
||||
}
|
||||
|
||||
[self.descriptionLabel sizeToFit];
|
||||
[self.descriptionLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerX.mas_equalTo(self.mas_centerX);
|
||||
make.top.mas_equalTo(self.headImg.mas_bottom).mas_offset(kScale390(10));
|
||||
make.height.mas_equalTo(30);
|
||||
make.width.mas_equalTo(self.descriptionLabel.frame.size.width);
|
||||
make.width.mas_lessThanOrEqualTo(self).multipliedBy(0.5);
|
||||
}];
|
||||
MASAttachKeys(self.descriptionLabel);
|
||||
|
||||
[self.editButton mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.mas_equalTo(self.descriptionLabel.mas_trailing).mas_equalTo(kScale390(3));
|
||||
make.top.mas_equalTo(self.descriptionLabel.mas_top);
|
||||
make.height.mas_equalTo(30);
|
||||
make.width.mas_equalTo(30);
|
||||
}];
|
||||
MASAttachKeys(self.editButton);
|
||||
|
||||
[self.idLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.mas_equalTo(self.mas_leading);
|
||||
make.top.mas_equalTo(self.descriptionLabel.mas_bottom).mas_offset(kScale390(8));
|
||||
make.height.mas_equalTo(30);
|
||||
make.width.mas_equalTo(self.frame.size.width);
|
||||
}];
|
||||
if (self.functionListView.subviews.count > 0) {
|
||||
[self.functionListView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.mas_equalTo(0);
|
||||
make.width.mas_equalTo(self.bounds.size.width);
|
||||
make.height.mas_equalTo(kScale390(95));
|
||||
make.top.mas_equalTo(self.idLabel.mas_bottom).mas_offset(kScale390(18));
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
}
|
||||
|
||||
- (void)headImageClick {
|
||||
if (self.headImgClickBlock && [self.class isMeSuper:self.groupInfo]) {
|
||||
self.headImgClickBlock();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)editButtonClick {
|
||||
if (self.editBtnClickBlock && [self.class isMeSuper:self.groupInfo]) {
|
||||
self.editBtnClickBlock();
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)isMeSuper:(V2TIMGroupInfo *)groupInfo {
|
||||
return [groupInfo.owner isEqualToString:[[V2TIMManager sharedInstance] getLoginUser]] && (groupInfo.role == V2TIM_GROUP_MEMBER_ROLE_SUPER);
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation TUIGroupProfileCardViewCell_Minimalist
|
||||
|
||||
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self) {
|
||||
[self setupViews];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setupViews {
|
||||
self.headerView = [[TUIGroupProfileHeaderView_Minimalist alloc] initWithFrame:CGRectMake(0, 0, Screen_Width, kScale390(355))];
|
||||
|
||||
[self.contentView addSubview:self.headerView];
|
||||
}
|
||||
|
||||
- (void)fillWithData:(TUIGroupProfileCardCellData_Minimalist *)data {
|
||||
[super fillWithData:data];
|
||||
self.cardData = data;
|
||||
|
||||
[self.headerView.headImg sd_setImageWithURL:data.avatarUrl placeholderImage:data.avatarImage];
|
||||
self.headerView.descriptionLabel.text = data.name;
|
||||
self.headerView.idLabel.text = [NSString stringWithFormat:@"ID: %@", data.identifier];
|
||||
}
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
if (self.headerView.functionListView.subviews.count > 0) {
|
||||
self.headerView.frame = CGRectMake(0, 0, self.contentView.bounds.size.width, kScale390(355));
|
||||
} else {
|
||||
self.headerView.frame = CGRectMake(0, 0, self.contentView.bounds.size.width, kScale390(257));
|
||||
}
|
||||
[self.headerView.descriptionLabel sizeToFit];
|
||||
self.headerView.itemViewList = self.itemViewList;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
@class TUIMemberDescribeCellData_Minimalist;
|
||||
@class TUIMemberCellData_Minimalist;
|
||||
|
||||
@interface TUIMemberDescribeCell_Minimalist : TUICommonTableViewCell
|
||||
|
||||
- (void)fillWithData:(TUIMemberDescribeCellData_Minimalist *)cellData;
|
||||
|
||||
@end
|
||||
|
||||
@interface TUIMemberCell_Minimalist : TUICommonTableViewCell
|
||||
|
||||
- (void)fillWithData:(TUIMemberCellData_Minimalist *)cellData;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,205 @@
|
||||
//
|
||||
// TUIMemberCell.m
|
||||
// TUIChat
|
||||
//
|
||||
// Created by xia on 2022/3/11.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIMemberCell_Minimalist.h"
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import <TUICore/TUIThemeManager.h>
|
||||
#import "TUIMemberCellData.h"
|
||||
|
||||
@interface TUIMemberDescribeCell_Minimalist ()
|
||||
@property(nonatomic, strong) UIView *containerView;
|
||||
|
||||
@property(nonatomic, strong) UILabel *titleLabel;
|
||||
@property(nonatomic, strong) UIImageView *icon;
|
||||
@property(nonatomic, strong) TUIMemberDescribeCellData *cellData;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TUIMemberDescribeCell_Minimalist
|
||||
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self) {
|
||||
[self setupViews];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setupViews {
|
||||
self.containerView = [[UIView alloc] initWithFrame:CGRectZero];
|
||||
self.containerView.backgroundColor = [UIColor tui_colorWithHex:@"#F9F9F9"];
|
||||
self.containerView.layer.cornerRadius = kScale390(20);
|
||||
[self addSubview:self.containerView];
|
||||
|
||||
self.icon = [[UIImageView alloc] initWithFrame:CGRectZero];
|
||||
[self.containerView addSubview:self.icon];
|
||||
|
||||
self.titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
self.titleLabel.textAlignment = NSTextAlignmentLeft;
|
||||
self.titleLabel.textColor = TIMCommonDynamicColor(@"form_title_color", @"#000000");
|
||||
[self.containerView addSubview:self.titleLabel];
|
||||
|
||||
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
}
|
||||
|
||||
#pragma mark - Public
|
||||
- (void)fillWithData:(TUIMemberDescribeCellData *)cellData {
|
||||
[super fillWithData:cellData];
|
||||
self.cellData = cellData;
|
||||
|
||||
self.titleLabel.text = cellData.title;
|
||||
[self.icon setImage:cellData.icon];
|
||||
|
||||
// tell constraints they need updating
|
||||
[self setNeedsUpdateConstraints];
|
||||
|
||||
// update constraints now so we can animate the change
|
||||
[self updateConstraintsIfNeeded];
|
||||
|
||||
[self layoutIfNeeded];
|
||||
}
|
||||
|
||||
+ (BOOL)requiresConstraintBasedLayout {
|
||||
return YES;
|
||||
}
|
||||
|
||||
// this is Apple's recommended place for adding/updating constraints
|
||||
- (void)updateConstraints {
|
||||
|
||||
[super updateConstraints];
|
||||
|
||||
CGFloat margin = kScale390(16);
|
||||
[self.containerView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.mas_equalTo(margin);
|
||||
make.top.mas_equalTo(0);
|
||||
make.trailing.mas_equalTo(-margin);
|
||||
make.height.mas_equalTo(kScale390(57));
|
||||
}];
|
||||
[self.icon mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.mas_equalTo(kScale390(20));
|
||||
make.centerY.mas_equalTo(self.containerView);
|
||||
make.width.height.mas_equalTo(kScale390(16));
|
||||
}];
|
||||
|
||||
[self.titleLabel sizeToFit];
|
||||
[self.titleLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerY.mas_equalTo(self.containerView);
|
||||
make.leading.mas_equalTo(self.icon.mas_trailing).mas_offset(kScale390(11));
|
||||
make.height.mas_equalTo(self.titleLabel.frame.size.height);
|
||||
make.trailing.mas_equalTo(-kScale390(11));
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface TUIMemberCell_Minimalist ()
|
||||
|
||||
@property(nonatomic, strong) UIImageView *avatarView;
|
||||
@property(nonatomic, strong) UILabel *titleLabel;
|
||||
@property(nonatomic, strong) UILabel *detailLabel;
|
||||
@property(nonatomic, strong) TUIMemberCellData *cellData;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TUIMemberCell_Minimalist
|
||||
|
||||
#pragma mark - Life cycle
|
||||
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self) {
|
||||
self.contentView.backgroundColor = TIMCommonDynamicColor(@"form_bg_color", @"#FFFFFF");
|
||||
|
||||
self.avatarView = [[UIImageView alloc] initWithImage:DefaultAvatarImage];
|
||||
[self.contentView addSubview:self.avatarView];
|
||||
|
||||
self.titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
|
||||
[self.contentView addSubview:self.titleLabel];
|
||||
self.titleLabel.textColor = TIMCommonDynamicColor(@"form_title_color", @"#000000");
|
||||
self.titleLabel.font = [UIFont boldSystemFontOfSize:kScale390(14)];
|
||||
|
||||
self.detailLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];
|
||||
[self.contentView addSubview:self.detailLabel];
|
||||
self.detailLabel.rtlAlignment = TUITextRTLAlignmentTrailing;
|
||||
self.detailLabel.textColor = TIMCommonDynamicColor(@"form_title_color", @"#000000");
|
||||
self.detailLabel.mm__centerY(self.avatarView.mm_centerY);
|
||||
|
||||
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
|
||||
|
||||
self.changeColorWhenTouched = YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
}
|
||||
|
||||
#pragma mark - Public
|
||||
- (void)fillWithData:(TUIMemberCellData *)cellData {
|
||||
[super fillWithData:cellData];
|
||||
self.cellData = cellData;
|
||||
|
||||
self.titleLabel.text = cellData.title;
|
||||
[self.avatarView sd_setImageWithURL:cellData.avatarUrL placeholderImage:DefaultAvatarImage];
|
||||
self.detailLabel.hidden = cellData.detail.length == 0;
|
||||
self.detailLabel.text = cellData.detail;
|
||||
// tell constraints they need updating
|
||||
[self setNeedsUpdateConstraints];
|
||||
|
||||
// update constraints now so we can animate the change
|
||||
[self updateConstraintsIfNeeded];
|
||||
|
||||
[self layoutIfNeeded];
|
||||
}
|
||||
|
||||
+ (BOOL)requiresConstraintBasedLayout {
|
||||
return YES;
|
||||
}
|
||||
|
||||
// this is Apple's recommended place for adding/updating constraints
|
||||
- (void)updateConstraints {
|
||||
|
||||
[super updateConstraints];
|
||||
|
||||
CGFloat imgWidth = kScale390(32);
|
||||
|
||||
[self.avatarView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.width.height.mas_equalTo(imgWidth);
|
||||
make.centerY.mas_equalTo(self.contentView.mas_centerY);
|
||||
make.leading.mas_equalTo(kScale390(24));
|
||||
}];
|
||||
if ([TUIConfig defaultConfig].avatarType == TAvatarTypeRounded) {
|
||||
self.avatarView.layer.masksToBounds = YES;
|
||||
self.avatarView.layer.cornerRadius = imgWidth / 2;
|
||||
} else if ([TUIConfig defaultConfig].avatarType == TAvatarTypeRadiusCorner) {
|
||||
self.avatarView.layer.masksToBounds = YES;
|
||||
self.avatarView.layer.cornerRadius = [TUIConfig defaultConfig].avatarCornerRadius;
|
||||
}
|
||||
|
||||
[self.titleLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerY.mas_equalTo(self.avatarView.mas_centerY);
|
||||
make.leading.mas_equalTo(self.avatarView.mas_trailing).mas_offset(4);
|
||||
make.height.mas_equalTo(kScale390(17));
|
||||
make.trailing.lessThanOrEqualTo(self.detailLabel.mas_leading).mas_offset(-5);
|
||||
}];
|
||||
|
||||
[self.detailLabel sizeToFit];
|
||||
[self.detailLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.centerY.mas_equalTo(self.avatarView.mas_centerY);
|
||||
make.height.mas_equalTo(20);
|
||||
make.trailing.mas_equalTo(self.contentView.mas_trailing).mas_offset(-12);
|
||||
make.width.mas_equalTo(self.detailLabel.frame.size.width);
|
||||
}];
|
||||
|
||||
|
||||
}
|
||||
@end
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
#import <TIMCommon/TUIBubbleMessageCell_Minimalist.h>
|
||||
#import <TIMCommon/TUITextView.h>
|
||||
#import "TUIChatDefine.h"
|
||||
#import "TUITextMessageCellData.h"
|
||||
|
||||
@interface TUITextMessageCell_Minimalist : TUIBubbleMessageCell_Minimalist <UITextViewDelegate>
|
||||
|
||||
/**
|
||||
*
|
||||
* TextView for display text message content
|
||||
*/
|
||||
@property(nonatomic, strong) TUITextView *textView;
|
||||
|
||||
/**
|
||||
*
|
||||
* Selected text content
|
||||
*/
|
||||
@property(nonatomic, strong) NSString *selectContent;
|
||||
|
||||
/**
|
||||
*
|
||||
* Callback for selected all text
|
||||
*/
|
||||
@property(nonatomic, strong) TUIChatSelectAllContentCallback selectAllContentContent;
|
||||
|
||||
@property TUITextMessageCellData *textData;
|
||||
|
||||
@property(nonatomic, strong) UIImageView *voiceReadPoint;
|
||||
|
||||
- (void)fillWithData:(TUITextMessageCellData *)data;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface TUITextMessageCell_Minimalist (TUILayoutConfiguration)
|
||||
|
||||
/**
|
||||
* The color of label which displays the text message content.
|
||||
* Used when the message direction is send.
|
||||
*/
|
||||
@property(nonatomic, class) UIColor *outgoingTextColor;
|
||||
|
||||
/**
|
||||
* The font of label which displays the text message content.
|
||||
* Used when the message direction is send.
|
||||
*/
|
||||
@property(nonatomic, class) UIFont *outgoingTextFont;
|
||||
|
||||
/**
|
||||
* The color of label which displays the text message content.
|
||||
* Used when the message direction is received.
|
||||
*/
|
||||
@property(nonatomic, class) UIColor *incommingTextColor;
|
||||
|
||||
/**
|
||||
* The font of label which displays the text message content.
|
||||
* Used when the message direction is received.
|
||||
*/
|
||||
@property(nonatomic, class) UIFont *incommingTextFont;
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,327 @@
|
||||
//
|
||||
// TUITextMessageCell_Minimalist.m
|
||||
// UIKit
|
||||
//
|
||||
// Created by annidyfeng on 2019/5/30.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUITextMessageCell_Minimalist.h"
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import <TUICore/TUICore.h>
|
||||
#import <TUICore/TUIGlobalization.h>
|
||||
|
||||
@interface TUITextMessageCell_Minimalist ()<TUITextViewDelegate>
|
||||
|
||||
@end
|
||||
@implementation TUITextMessageCell_Minimalist
|
||||
|
||||
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self) {
|
||||
self.textView = [[TUITextView alloc] init];
|
||||
self.textView.backgroundColor = [UIColor clearColor];
|
||||
self.textView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0);
|
||||
self.textView.textContainer.lineFragmentPadding = 0;
|
||||
self.textView.scrollEnabled = NO;
|
||||
self.textView.editable = NO;
|
||||
self.textView.delegate = self;
|
||||
self.textView.tuiTextViewDelegate = self;
|
||||
self.bubbleView.userInteractionEnabled = YES;
|
||||
[self.bubbleView addSubview:self.textView];
|
||||
[self.container bringSubviewToFront:self.msgStatusView];
|
||||
self.bottomContainer = [[UIView alloc] init];
|
||||
[self.contentView addSubview:self.bottomContainer];
|
||||
|
||||
self.voiceReadPoint = [[UIImageView alloc] init];
|
||||
self.voiceReadPoint.backgroundColor = [UIColor redColor];
|
||||
self.voiceReadPoint.frame = CGRectMake(0, 0, 5, 5);
|
||||
self.voiceReadPoint.hidden = YES;
|
||||
[self.voiceReadPoint.layer setCornerRadius:self.voiceReadPoint.frame.size.width / 2];
|
||||
[self.voiceReadPoint.layer setMasksToBounds:YES];
|
||||
[self.bubbleView addSubview:self.voiceReadPoint];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)prepareForReuse {
|
||||
[super prepareForReuse];
|
||||
for (UIView *view in self.bottomContainer.subviews) {
|
||||
[view removeFromSuperview];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onLongPressTextViewMessage:(UITextView *)textView {
|
||||
if (self.delegate && [self.delegate respondsToSelector:@selector(onLongPressMessage:)]) {
|
||||
[self.delegate onLongPressMessage:self];
|
||||
}
|
||||
}
|
||||
|
||||
// Override
|
||||
- (void)notifyBottomContainerReadyOfData:(TUIMessageCellData *)cellData {
|
||||
NSDictionary *param = @{TUICore_TUIChatExtension_BottomContainer_CellData : self.textData};
|
||||
[TUICore raiseExtension:TUICore_TUIChatExtension_BottomContainer_MinimalistExtensionID parentView:self.bottomContainer param:param];
|
||||
}
|
||||
|
||||
- (void)fillWithData:(TUITextMessageCellData *)data;
|
||||
{
|
||||
// set data
|
||||
[super fillWithData:data];
|
||||
self.textData = data;
|
||||
self.selectContent = data.content;
|
||||
self.voiceReadPoint.hidden = !data.showUnreadPoint;
|
||||
self.bottomContainer.hidden = CGSizeEqualToSize(data.bottomContainerSize, CGSizeZero);
|
||||
|
||||
UIColor *textColor = self.class.incommingTextColor;
|
||||
UIFont *textFont = self.class.incommingTextFont;
|
||||
if (data.direction == MsgDirectionIncoming) {
|
||||
textColor = self.class.incommingTextColor;
|
||||
textFont = self.class.incommingTextFont;
|
||||
} else {
|
||||
textColor = self.class.outgoingTextColor;
|
||||
textFont = self.class.outgoingTextFont;
|
||||
}
|
||||
self.textView.attributedText = [data getContentAttributedString:textFont];
|
||||
self.textView.textColor = textColor;
|
||||
self.textView.font = textFont;
|
||||
self.textView.textAlignment = isRTL()?NSTextAlignmentRight:NSTextAlignmentLeft;
|
||||
|
||||
// tell constraints they need updating
|
||||
[self setNeedsUpdateConstraints];
|
||||
|
||||
// update constraints now so we can animate the change
|
||||
[self updateConstraintsIfNeeded];
|
||||
|
||||
[self layoutIfNeeded];
|
||||
}
|
||||
|
||||
+ (BOOL)requiresConstraintBasedLayout {
|
||||
return YES;
|
||||
}
|
||||
|
||||
// this is Apple's recommended place for adding/updating constraints
|
||||
- (void)updateConstraints {
|
||||
|
||||
[super updateConstraints];
|
||||
// self.textView.frame = (CGRect){.origin = self.textData.textOrigin, .size = self.textData.textSize};
|
||||
[self.textView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.mas_equalTo(self.bubbleView.mas_leading).mas_offset(ceil(self.textData.textOrigin.x));
|
||||
make.top.mas_equalTo(self.bubbleView.mas_top).mas_offset(ceil(self.textData.textOrigin.y));
|
||||
make.width.mas_equalTo(ceil(self.textData.textSize.width));
|
||||
make.height.mas_equalTo(ceil(self.textData.textSize.height));
|
||||
}];
|
||||
MASAttachKeys(self.textView);
|
||||
if (self.voiceReadPoint.hidden == NO) {
|
||||
[self.voiceReadPoint mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(self.bubbleView);
|
||||
make.leading.mas_equalTo(self.bubbleView.mas_trailing).mas_offset(1);
|
||||
make.size.mas_equalTo(CGSizeMake(5, 5));
|
||||
}];
|
||||
}
|
||||
MASAttachKeys(self.voiceReadPoint);
|
||||
[self layoutBottomContainer];
|
||||
|
||||
}
|
||||
- (void)layoutSubviews {
|
||||
[super layoutSubviews];
|
||||
}
|
||||
|
||||
- (void)layoutBottomContainer {
|
||||
if (CGSizeEqualToSize(self.textData.bottomContainerSize, CGSizeZero)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGSize size = self.textData.bottomContainerSize;
|
||||
/// TransitionView should not cover the replyView.
|
||||
/// Add an extra tiny offset to the left or right of TransitionView if replyView is visible.
|
||||
CGFloat offset = self.replyLineView.hidden ? 0 : 1;
|
||||
[self.bottomContainer mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
if (self.textData.direction == MsgDirectionIncoming) {
|
||||
make.leading.mas_equalTo(self.container.mas_leading).mas_offset(offset);
|
||||
} else {
|
||||
make.trailing.mas_equalTo(self.container.mas_trailing).mas_offset(-offset);
|
||||
}
|
||||
make.top.mas_equalTo(self.bubbleView.mas_bottom).mas_offset(self.messageData.messageContainerAppendSize.height + 6);
|
||||
make.size.mas_equalTo(size);
|
||||
}];
|
||||
|
||||
if (!self.messageModifyRepliesButton.hidden) {
|
||||
CGRect oldRect = self.messageModifyRepliesButton.frame;
|
||||
CGRect newRect = CGRectMake(oldRect.origin.x, CGRectGetMaxY(self.bottomContainer.frame) + 5, oldRect.size.width, oldRect.size.height);
|
||||
self.messageModifyRepliesButton.frame = newRect;
|
||||
}
|
||||
|
||||
for (UIView *view in self.replyAvatarImageViews) {
|
||||
CGRect oldRect = view.frame;
|
||||
CGRect newRect = CGRectMake(oldRect.origin.x, CGRectGetMaxY(self.bottomContainer.frame) + 5, oldRect.size.width, oldRect.size.height);
|
||||
view.frame = newRect;
|
||||
}
|
||||
if (!self.replyLineView.hidden) {
|
||||
CGRect oldRect = self.retryView.frame;
|
||||
CGRect newRect = CGRectMake(oldRect.origin.x, oldRect.origin.y, oldRect.size.width, oldRect.size.height + self.bottomContainer.mm_h);
|
||||
self.retryView.frame = newRect;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)textViewDidChangeSelection:(UITextView *)textView {
|
||||
NSAttributedString *selectedString = [textView.attributedText attributedSubstringFromRange:textView.selectedRange];
|
||||
if (self.selectAllContentContent && selectedString.length > 0) {
|
||||
if (selectedString.length == textView.attributedText.length) {
|
||||
self.selectAllContentContent(YES);
|
||||
} else {
|
||||
self.selectAllContentContent(NO);
|
||||
}
|
||||
}
|
||||
if (selectedString.length > 0) {
|
||||
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init];
|
||||
[attributedString appendAttributedString:selectedString];
|
||||
NSUInteger offsetLocation = 0;
|
||||
for (NSDictionary *emojiLocation in self.textData.emojiLocations) {
|
||||
NSValue *key = emojiLocation.allKeys.firstObject;
|
||||
NSAttributedString *originStr = emojiLocation[key];
|
||||
NSRange currentRange = [key rangeValue];
|
||||
/**
|
||||
* After each emoji is replaced, the length of the string will change, and the actual location of the emoji will also change accordingly.
|
||||
*/
|
||||
currentRange.location += offsetLocation;
|
||||
if (currentRange.location >= textView.selectedRange.location) {
|
||||
currentRange.location -= textView.selectedRange.location;
|
||||
if (currentRange.location + currentRange.length <= attributedString.length) {
|
||||
[attributedString replaceCharactersInRange:currentRange withAttributedString:originStr];
|
||||
offsetLocation += originStr.length - currentRange.length;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.selectContent = attributedString.string;
|
||||
} else {
|
||||
self.selectContent = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - TUIMessageCelllProtocol
|
||||
+ (CGFloat)getEstimatedHeight:(TUIMessageCellData *)data {
|
||||
return 44.f;
|
||||
}
|
||||
|
||||
+ (CGFloat)getHeight:(TUIMessageCellData *)data withWidth:(CGFloat)width {
|
||||
NSAssert([data isKindOfClass:TUITextMessageCellData.class], @"data must be kind of TUITextMessageCellData");
|
||||
TUITextMessageCellData *textCellData = (TUITextMessageCellData *)data;
|
||||
|
||||
CGFloat height = [super getHeight:textCellData withWidth:width];
|
||||
if (textCellData.bottomContainerSize.height > 0) {
|
||||
height += textCellData.bottomContainerSize.height + 6;
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
+ (CGSize)getContentSize:(TUIMessageCellData *)data {
|
||||
NSAssert([data isKindOfClass:TUITextMessageCellData.class], @"data must be kind of TUITextMessageCellData");
|
||||
TUITextMessageCellData *textCellData = (TUITextMessageCellData *)data;
|
||||
|
||||
UIFont *textFont = textCellData.direction == MsgDirectionIncoming ? self.incommingTextFont : self.outgoingTextFont;
|
||||
NSAttributedString *attributeString = [textCellData getContentAttributedString:textFont];
|
||||
CGRect rect = [attributeString boundingRectWithSize:CGSizeMake(TTextMessageCell_Text_Width_Max, MAXFLOAT)
|
||||
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
|
||||
context:nil];
|
||||
CGSize size = rect.size;
|
||||
|
||||
CGRect rect2 = [attributeString boundingRectWithSize:CGSizeMake(MAXFLOAT, [textFont lineHeight])
|
||||
options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
|
||||
context:nil];
|
||||
CGSize size2 = rect2.size;
|
||||
|
||||
// If there are multiple lines, determine whether the font width of the last line exceeds the position of the message status. If so, the message status will wrap.
|
||||
// If there is only one line, directly add the width of the message status
|
||||
int max_width = size.height > [textFont lineHeight] ? size.width : TTextMessageCell_Text_Width_Max;
|
||||
if ((int)size2.width / max_width > 1) {
|
||||
if ((int)size2.width % max_width == 0 || (int)size2.width % max_width + textCellData.msgStatusSize.width >= max_width) {
|
||||
size.height += textCellData.msgStatusSize.height;
|
||||
}
|
||||
} else {
|
||||
size.width += textCellData.msgStatusSize.width + kScale390(10);
|
||||
}
|
||||
|
||||
textCellData.textSize = size;
|
||||
CGFloat y = textCellData.cellLayout.bubbleInsets.top + [TUIBubbleMessageCell_Minimalist getBubbleTop:textCellData];
|
||||
textCellData.textOrigin = CGPointMake(textCellData.cellLayout.bubbleInsets.left, y);
|
||||
|
||||
size.height += textCellData.cellLayout.bubbleInsets.top + textCellData.cellLayout.bubbleInsets.bottom;
|
||||
size.width += textCellData.cellLayout.bubbleInsets.left + textCellData.cellLayout.bubbleInsets.right;
|
||||
|
||||
if (textCellData.direction == MsgDirectionIncoming) {
|
||||
size.height = MAX(size.height, TUIBubbleMessageCell_Minimalist.incommingBubble.size.height);
|
||||
} else {
|
||||
size.height = MAX(size.height, TUIBubbleMessageCell_Minimalist.outgoingBubble.size.height);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation TUITextMessageCell_Minimalist (TUILayoutConfiguration)
|
||||
|
||||
+ (void)initialize {
|
||||
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(onThemeChanged) name:TUIDidApplyingThemeChangedNotfication object:nil];
|
||||
}
|
||||
|
||||
static UIColor *gOutgoingTextColor;
|
||||
|
||||
+ (UIColor *)outgoingTextColor {
|
||||
if (!gOutgoingTextColor) {
|
||||
gOutgoingTextColor = TUIChatDynamicColor(@"chat_text_message_send_text_color", @"#000000");
|
||||
}
|
||||
return gOutgoingTextColor;
|
||||
}
|
||||
|
||||
+ (void)setOutgoingTextColor:(UIColor *)outgoingTextColor {
|
||||
gOutgoingTextColor = outgoingTextColor;
|
||||
}
|
||||
|
||||
static UIFont *gOutgoingTextFont;
|
||||
|
||||
+ (UIFont *)outgoingTextFont {
|
||||
if (!gOutgoingTextFont) {
|
||||
gOutgoingTextFont = [UIFont systemFontOfSize:16];
|
||||
}
|
||||
return gOutgoingTextFont;
|
||||
}
|
||||
|
||||
+ (void)setOutgoingTextFont:(UIFont *)outgoingTextFont {
|
||||
gOutgoingTextFont = outgoingTextFont;
|
||||
}
|
||||
|
||||
static UIColor *gIncommingTextColor;
|
||||
|
||||
+ (UIColor *)incommingTextColor {
|
||||
if (!gIncommingTextColor) {
|
||||
gIncommingTextColor = TUIChatDynamicColor(@"chat_text_message_receive_text_color", @"#000000");
|
||||
}
|
||||
return gIncommingTextColor;
|
||||
}
|
||||
|
||||
+ (void)setIncommingTextColor:(UIColor *)incommingTextColor {
|
||||
gIncommingTextColor = incommingTextColor;
|
||||
}
|
||||
|
||||
static UIFont *gIncommingTextFont;
|
||||
|
||||
+ (UIFont *)incommingTextFont {
|
||||
if (!gIncommingTextFont) {
|
||||
gIncommingTextFont = [UIFont systemFontOfSize:16];
|
||||
}
|
||||
return gIncommingTextFont;
|
||||
}
|
||||
|
||||
+ (void)setIncommingTextFont:(UIFont *)incommingTextFont {
|
||||
gIncommingTextFont = incommingTextFont;
|
||||
}
|
||||
|
||||
+ (void)onThemeChanged {
|
||||
gOutgoingTextColor = nil;
|
||||
gIncommingTextColor = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user