提交
This commit is contained in:
16
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIGroupCreatedCell.h
Normal file
16
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIGroupCreatedCell.h
Normal file
@@ -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 : TUISystemMessageCell
|
||||
|
||||
- (void)fillWithData:(TUIGroupCreatedCellData *)data;
|
||||
|
||||
@end
|
||||
17
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIGroupCreatedCell.m
Normal file
17
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIGroupCreatedCell.m
Normal file
@@ -0,0 +1,17 @@
|
||||
//
|
||||
// MyCustomCell.m
|
||||
// TUIKitDemo
|
||||
//
|
||||
// Created by annidyfeng on 2019/6/10.
|
||||
// Copyright © 2019 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIGroupCreatedCell.h"
|
||||
|
||||
@implementation TUIGroupCreatedCell
|
||||
|
||||
- (void)fillWithData:(TUIGroupCreatedCellData *)data {
|
||||
[super fillWithData:data];
|
||||
}
|
||||
|
||||
@end
|
||||
48
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIInputMoreCell.h
Normal file
48
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIInputMoreCell.h
Normal file
@@ -0,0 +1,48 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
/**
|
||||
*
|
||||
*
|
||||
* This document declares modules for implementing "more" units.
|
||||
* More units, that is, the UI interface that appears after clicking the "+" in the lower right corner of the chat interface.
|
||||
* At present, more units provide four multimedia sending functions of camera, video, picture, and file, and you can also customize it according to your needs.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "TUIInputMoreCellData.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TUIInputMoreCell
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@interface TUIInputMoreCell : UICollectionViewCell
|
||||
|
||||
/**
|
||||
* The icons corresponding to more cells are obtained from the image of TUIInputMoreCellData.
|
||||
* The icons of each unit are different, which are used to visually represent the corresponding functions of the unit.
|
||||
*/
|
||||
@property(nonatomic, strong) UIImageView *image;
|
||||
|
||||
/**
|
||||
* The label corresponding to more cells, the text content of which is obtained from the title of TUIInputMoreCellData.
|
||||
* The names of each unit are different (such as camera, video, file, album, etc.), which are used to display the corresponding functions of the unit in text
|
||||
* form below the icon.
|
||||
*/
|
||||
@property(nonatomic, strong) UILabel *title;
|
||||
|
||||
@property(nonatomic, strong) TUIInputMoreCellData *data;
|
||||
|
||||
/**
|
||||
* Whether to disable the default selection behavior encapsulated in TUIKit, such as group live broadcast by default to create live room and other behaviors,
|
||||
* default: NO
|
||||
*/
|
||||
@property(nonatomic, assign) BOOL disableDefaultSelectAction;
|
||||
|
||||
- (void)fillWithData:(TUIInputMoreCellData *)data;
|
||||
|
||||
+ (CGSize)getSize;
|
||||
|
||||
@end
|
||||
67
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIInputMoreCell.m
Normal file
67
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIInputMoreCell.m
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// TMoreCell.m
|
||||
// UIKit
|
||||
//
|
||||
// Created by annidyfeng on 2019/5/22.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIInputMoreCell.h"
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
|
||||
@implementation TUIInputMoreCell
|
||||
|
||||
- (id)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self setupViews];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)setupViews {
|
||||
_image = [[UIImageView alloc] init];
|
||||
_image.contentMode = UIViewContentModeScaleAspectFit;
|
||||
[self addSubview:_image];
|
||||
|
||||
_title = [[UILabel alloc] init];
|
||||
[_title setFont:[UIFont systemFontOfSize:10]];
|
||||
[_title setTextColor:[UIColor grayColor]];
|
||||
_title.textAlignment = NSTextAlignmentCenter;
|
||||
[self addSubview:_title];
|
||||
}
|
||||
|
||||
- (void)fillWithData:(TUIInputMoreCellData *)data {
|
||||
// set data
|
||||
_data = data;
|
||||
self.hidden = (data == nil) ? YES : NO;
|
||||
_image.image = data.image;
|
||||
[_title setText:data.title];
|
||||
// update layout
|
||||
CGSize menuSize = TMoreCell_Image_Size;
|
||||
_image.frame = CGRectMake(0, 0, menuSize.width, menuSize.height);
|
||||
_title.frame = CGRectMake(0, _image.frame.origin.y + _image.frame.size.height, _image.frame.size.width + 10, TMoreCell_Title_Height);
|
||||
_title.center = CGPointMake(_image.center.x, _title.center.y);
|
||||
}
|
||||
|
||||
+ (CGSize)getSize {
|
||||
CGSize menuSize = TMoreCell_Image_Size;
|
||||
return CGSizeMake(menuSize.width, menuSize.height + TMoreCell_Title_Height);
|
||||
}
|
||||
@end
|
||||
|
||||
@interface IUChatView : UIView
|
||||
@property(nonatomic, strong) UIView *view;
|
||||
@end
|
||||
|
||||
@implementation IUChatView
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
self.view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
|
||||
[self addSubview:self.view];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
16
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIMemberCell.h
Normal file
16
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIMemberCell.h
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TUIMemberCellData;
|
||||
@interface TUIMemberCell : TUICommonTableViewCell
|
||||
|
||||
- (void)fillWithData:(TUIMemberCellData *)cellData;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
115
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIMemberCell.m
Normal file
115
TUIKit/TUIChat/UI_Classic/Cell/Base/TUIMemberCell.m
Normal file
@@ -0,0 +1,115 @@
|
||||
//
|
||||
// TUIMemberCell.m
|
||||
// TUIChat
|
||||
//
|
||||
// Created by xia on 2022/3/11.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUIMemberCell.h"
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import <TUICore/TUIThemeManager.h>
|
||||
#import "TUIMemberCellData.h"
|
||||
|
||||
@interface TUIMemberCell ()
|
||||
|
||||
@property(nonatomic, strong) UIImageView *avatarView;
|
||||
@property(nonatomic, strong) UILabel *titleLabel;
|
||||
@property(nonatomic, strong) UILabel *detailLabel;
|
||||
@property(nonatomic, strong) TUIMemberCellData *cellData;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TUIMemberCell
|
||||
|
||||
#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.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 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(34);
|
||||
|
||||
[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(12));
|
||||
}];
|
||||
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(12);
|
||||
make.height.mas_equalTo(20);
|
||||
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(-3);
|
||||
make.width.mas_equalTo(self.detailLabel.frame.size.width);
|
||||
}];
|
||||
|
||||
|
||||
}
|
||||
@end
|
||||
75
TUIKit/TUIChat/UI_Classic/Cell/Base/TUITextMessageCell.h
Normal file
75
TUIKit/TUIChat/UI_Classic/Cell/Base/TUITextMessageCell.h
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
// Created by Tencent on 2023/06/09.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
#import <TIMCommon/TUIBubbleMessageCell.h>
|
||||
#import <TIMCommon/TUITextView.h>
|
||||
#import "TUIChatDefine.h"
|
||||
#import "TUITextMessageCellData.h"
|
||||
|
||||
@class TUITextView;
|
||||
|
||||
typedef void (^TUIChatSelectAllContentCallback)(BOOL);
|
||||
|
||||
@interface TUITextMessageCell : TUIBubbleMessageCell <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;
|
||||
|
||||
/// Data for text message cell.
|
||||
@property(nonatomic, strong) TUITextMessageCellData *textData;
|
||||
|
||||
@property(nonatomic, strong) UIImageView *voiceReadPoint;
|
||||
|
||||
- (void)fillWithData:(TUITextMessageCellData *)data;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface TUITextMessageCell (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;
|
||||
|
||||
+ (void)setMaxTextSize:(CGSize)maxTextSz;
|
||||
|
||||
@end
|
||||
339
TUIKit/TUIChat/UI_Classic/Cell/Base/TUITextMessageCell.m
Normal file
339
TUIKit/TUIChat/UI_Classic/Cell/Base/TUITextMessageCell.m
Normal file
@@ -0,0 +1,339 @@
|
||||
//
|
||||
// TUITextMessageCell.m
|
||||
// UIKit
|
||||
//
|
||||
// Created by annidyfeng on 2019/5/30.
|
||||
// Copyright © 2023 Tencent. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TUITextMessageCell.h"
|
||||
#import <TIMCommon/TIMCommonModel.h>
|
||||
#import <TIMCommon/TIMDefine.h>
|
||||
#import <TUICore/TUICore.h>
|
||||
#import <TUICore/TUIGlobalization.h>
|
||||
#import "TUIFaceView.h"
|
||||
#import <TUICore/UIColor+TUIHexColor.h>
|
||||
|
||||
#ifndef CGFLOAT_CEIL
|
||||
#ifdef CGFLOAT_IS_DOUBLE
|
||||
#define CGFLOAT_CEIL(value) ceil(value)
|
||||
#else
|
||||
#define CGFLOAT_CEIL(value) ceilf(value)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@interface TUITextMessageCell ()<TUITextViewDelegate>
|
||||
@end
|
||||
|
||||
@implementation TUITextMessageCell
|
||||
|
||||
- (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.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_ClassicExtensionID 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;
|
||||
|
||||
// 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 mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.leading.mas_equalTo(self.bubbleView.mas_leading).mas_offset(self.textData.textOrigin.x);
|
||||
make.top.mas_equalTo(self.bubbleView.mas_top).mas_offset(self.textData.textOrigin.y);
|
||||
make.size.mas_equalTo(self.textData.textSize);
|
||||
}];
|
||||
|
||||
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));
|
||||
}];
|
||||
}
|
||||
|
||||
BOOL hasRiskContent = self.messageData.innerMessage.hasRiskContent;
|
||||
if (hasRiskContent ) {
|
||||
[self.securityStrikeView mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
make.top.mas_equalTo(self.textView.mas_bottom);
|
||||
make.width.mas_equalTo(self.bubbleView);
|
||||
make.bottom.mas_equalTo(self.container).mas_offset(- self.messageData.messageContainerAppendSize.height);
|
||||
}];
|
||||
}
|
||||
[self layoutBottomContainer];
|
||||
|
||||
}
|
||||
|
||||
- (void)layoutBottomContainer {
|
||||
if (CGSizeEqualToSize(self.textData.bottomContainerSize, CGSizeZero)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGSize size = self.textData.bottomContainerSize;
|
||||
|
||||
[self.bottomContainer mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
if (self.textData.direction == MsgDirectionIncoming) {
|
||||
make.leading.mas_equalTo(self.container.mas_leading);
|
||||
}
|
||||
else {
|
||||
make.trailing.mas_equalTo(self.container.mas_trailing);
|
||||
}
|
||||
make.top.mas_equalTo(self.container.mas_bottom).offset(6);
|
||||
make.size.mas_equalTo(size);
|
||||
}];
|
||||
|
||||
CGFloat repliesBtnTextWidth = self.messageModifyRepliesButton.frame.size.width;
|
||||
if (!self.messageModifyRepliesButton.hidden) {
|
||||
[self.messageModifyRepliesButton mas_remakeConstraints:^(MASConstraintMaker *make) {
|
||||
if (self.textData.direction == MsgDirectionIncoming) {
|
||||
make.leading.mas_equalTo(self.container.mas_leading);
|
||||
} else {
|
||||
make.trailing.mas_equalTo(self.container.mas_trailing);
|
||||
}
|
||||
make.top.mas_equalTo(self.bottomContainer.mas_bottom);
|
||||
make.size.mas_equalTo(CGSizeMake(repliesBtnTextWidth + 10, 30));
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (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;
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:@"kTUIChatPopMenuWillHideNotification" object:nil];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - TUIMessageCellProtocol
|
||||
|
||||
+ (CGFloat)getEstimatedHeight:(TUIMessageCellData *)data {
|
||||
return 60.f;
|
||||
}
|
||||
|
||||
+ (CGFloat)getHeight:(TUIMessageCellData *)data withWidth:(CGFloat)width {
|
||||
CGFloat height = [super getHeight:data withWidth:width];
|
||||
if (data.bottomContainerSize.height > 0) {
|
||||
height += data.bottomContainerSize.height + kScale375(6);
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
static CGSize gMaxTextSize;
|
||||
+ (void)setMaxTextSize:(CGSize)maxTextSz {
|
||||
gMaxTextSize = maxTextSz;
|
||||
}
|
||||
+ (CGSize)getContentSize:(TUIMessageCellData *)data {
|
||||
NSAssert([data isKindOfClass:TUITextMessageCellData.class], @"data must be kind of TUITextMessageCellData");
|
||||
TUITextMessageCellData *textCellData = (TUITextMessageCellData *)data;
|
||||
|
||||
NSAttributedString *attributeString = [textCellData getContentAttributedString:
|
||||
data.direction == MsgDirectionIncoming ? self.incommingTextFont : self.outgoingTextFont];
|
||||
|
||||
if (CGSizeEqualToSize(gMaxTextSize, CGSizeZero)) {
|
||||
gMaxTextSize = CGSizeMake(TTextMessageCell_Text_Width_Max, MAXFLOAT);
|
||||
}
|
||||
CGSize contentSize = [textCellData getContentAttributedStringSize:attributeString maxTextSize:gMaxTextSize];
|
||||
textCellData.textSize = contentSize;
|
||||
|
||||
CGPoint textOrigin = CGPointMake(textCellData.cellLayout.bubbleInsets.left,
|
||||
textCellData.cellLayout.bubbleInsets.top);
|
||||
textCellData.textOrigin = textOrigin;
|
||||
|
||||
CGFloat height = contentSize.height;
|
||||
CGFloat width = contentSize.width;
|
||||
|
||||
height += textCellData.cellLayout.bubbleInsets.top;
|
||||
height += textCellData.cellLayout.bubbleInsets.bottom;
|
||||
|
||||
width += textCellData.cellLayout.bubbleInsets.left;
|
||||
width += textCellData.cellLayout.bubbleInsets.right;
|
||||
|
||||
if (textCellData.direction == MsgDirectionIncoming) {
|
||||
height = MAX(height, TUIBubbleMessageCell.incommingBubble.size.height);
|
||||
} else {
|
||||
height = MAX(height, TUIBubbleMessageCell.outgoingBubble.size.height);
|
||||
}
|
||||
|
||||
BOOL hasRiskContent = textCellData.innerMessage.hasRiskContent;
|
||||
if (hasRiskContent) {
|
||||
width = MAX(width, 200);// width must more than TIMCommonLocalizableString(TUIKitMessageTypeSecurityStrike)
|
||||
height += kTUISecurityStrikeViewTopLineMargin;
|
||||
height += kTUISecurityStrikeViewTopLineToBottom;
|
||||
}
|
||||
|
||||
CGSize size = CGSizeMake(width, height);
|
||||
return size;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation TUITextMessageCell (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