1010
1111#import " XHMessageBubbleHelper.h"
1212
13- #define kMarginTop 8 .0f
14- #define kMarginBottom 2 .0f
15- #define kPaddingTop 12 .0f
16- #define kBubblePaddingRight 14 .0f
13+ #define kTextMarginTop 12 .0f // 文本上间隙
14+ #define kTextMarginBottom 12 .0f // 文本下间隙
1715
18- #define kVoiceMargin 20 .0f
16+ #define kVoiceMargin 20 .0f // 语音间隙
1917
20- #define kXHArrowMarginWidth 14
18+ #define kXHArrowMarginWidth 14 .0f // 箭头宽度
19+
20+ #define kTextHorizontalBubblePadding 16 .0f // 文本的水平间隙
2121
2222@interface XHMessageBubbleView ()
2323
@@ -57,8 +57,11 @@ + (CGSize)neededSizeForText:(NSString *)text {
5757
5858 CGFloat dyWidth = [XHMessageBubbleView neededWidthForText: text];
5959
60- CGSize textSize = [SETextView frameRectWithAttributtedString: [[XHMessageBubbleHelper sharedMessageBubbleHelper ] bubbleAttributtedStringWithText: text] constraintSize: CGSizeMake (maxWidth, MAXFLOAT) lineSpacing: kXHTextLineSpacing font: [[XHMessageBubbleView appearance ] font ]].size ;
61- return CGSizeMake ((dyWidth > textSize.width ? textSize.width : dyWidth) + kBubblePaddingRight * 2 + kXHArrowMarginWidth , textSize.height + kMarginTop * 2 );
60+ CGSize textSize = [SETextView frameRectWithAttributtedString: [[XHMessageBubbleHelper sharedMessageBubbleHelper ] bubbleAttributtedStringWithText: text]
61+ constraintSize: CGSizeMake (maxWidth, MAXFLOAT)
62+ lineSpacing: kXHTextLineSpacing
63+ font: [[XHMessageBubbleView appearance ] font ]].size ;
64+ return CGSizeMake ((dyWidth > textSize.width ? textSize.width : dyWidth), textSize.height );
6265}
6366
6467+ (CGSize)neededSizeForPhoto : (UIImage *)photo {
@@ -70,20 +73,21 @@ + (CGSize)neededSizeForPhoto:(UIImage *)photo {
7073+ (CGSize)neededSizeForVoicePath : (NSString *)voicePath voiceDuration : (NSString *)voiceDuration {
7174 // 这里的100只是暂时固定,到时候会根据一个函数来计算
7275 float gapDuration = (!voiceDuration || voiceDuration.length == 0 ? -1 : [voiceDuration floatValue ] - 1 .0f );
73- CGSize voiceSize = CGSizeMake (100 + (gapDuration > 0 ? (120.0 / (60 - 1 ) * gapDuration) : 0 ), 30 );
76+ CGSize voiceSize = CGSizeMake (100 + (gapDuration > 0 ? (120.0 / (60 - 1 ) * gapDuration) : 0 ), 42 );
7477 return voiceSize;
7578}
7679
7780+ (CGFloat)calculateCellHeightWithMessage : (id <XHMessageModel>)message {
7881 CGSize size = [XHMessageBubbleView getBubbleFrameWithMessage: message];
79- return size.height + kMarginTop + kMarginBottom ;
82+ return size.height + kTextMarginTop + kTextMarginBottom ;
8083}
8184
8285+ (CGSize)getBubbleFrameWithMessage : (id <XHMessageModel>)message {
8386 CGSize bubbleSize;
8487 switch (message.messageMediaType ) {
8588 case XHBubbleMessageMediaTypeText: {
8689 bubbleSize = [XHMessageBubbleView neededSizeForText: message.text];
90+ bubbleSize = CGSizeMake (bubbleSize.width + kTextHorizontalBubblePadding * 2 + kXHArrowMarginWidth , bubbleSize.height + kTextMarginTop + kTextMarginBottom );
8791 break ;
8892 }
8993 case XHBubbleMessageMediaTypePhoto: {
@@ -131,15 +135,25 @@ - (UIFont *)font {
131135
132136
133137- (CGRect)bubbleFrame {
138+
139+ // 1.先得到文字的宽度和高度
134140 CGSize bubbleSize = [XHMessageBubbleView getBubbleFrameWithMessage: self .message];
135141
136- return CGRectIntegral (CGRectMake ((self.message .bubbleMessageType == XHBubbleMessageTypeSending ? CGRectGetWidth (self.bounds ) - bubbleSize.width : 0 .0f ),
137- kMarginTop ,
142+ // 2.计算起泡的大小和位置
143+ CGFloat paddingX = 0 .0f ;
144+ if (self.message .bubbleMessageType == XHBubbleMessageTypeSending) {
145+ paddingX = CGRectGetWidth (self.bounds ) - bubbleSize.width ;
146+ }
147+
148+ return CGRectIntegral (
149+ CGRectMake (paddingX,
150+ kTextMarginTop ,
138151 bubbleSize.width ,
139- bubbleSize.height + kMarginTop + kMarginBottom ));
152+ bubbleSize.height )
153+ );
140154}
141155
142- #pragma mark - Life cycle
156+ #pragma mark - Configure Methods
143157
144158- (void )configureCellWithMessage : (id <XHMessageModel>)message {
145159 _message = message;
@@ -252,6 +266,22 @@ - (void)configureMessageDisplayMediaWithMessage:(id <XHMessageModel>)message {
252266 [self setNeedsLayout ];
253267}
254268
269+ - (void )configureVoiceDurationLabelFrameWithBubbleFrame : (CGRect)bubbleFrame {
270+ CGRect voiceFrame = _voiceDurationLabel.frame ;
271+ voiceFrame.origin .x = (self.message .bubbleMessageType == XHBubbleMessageTypeSending ? bubbleFrame.origin .x - CGRectGetWidth (voiceFrame) : bubbleFrame.origin .x + bubbleFrame.size .width );
272+ _voiceDurationLabel.frame = voiceFrame;
273+ _voiceDurationLabel.textAlignment = (self.message .bubbleMessageType == XHBubbleMessageTypeSending ? NSTextAlignmentRight : NSTextAlignmentLeft);
274+ }
275+
276+ - (void )configureVoiceUnreadDotImageViewFrameWithBubbleFrame : (CGRect)bubbleFrame {
277+ CGRect voiceUnreadDotFrame = _voiceUnreadDotImageView.frame ;
278+ voiceUnreadDotFrame.origin .x = (self.message .bubbleMessageType == XHBubbleMessageTypeSending ? bubbleFrame.origin .x + CGRectGetWidth (voiceUnreadDotFrame) : bubbleFrame.origin .x + bubbleFrame.size .width - CGRectGetWidth (voiceUnreadDotFrame) * 2 );
279+ voiceUnreadDotFrame.origin .y = bubbleFrame.size .height / 2.0 + CGRectGetHeight (voiceUnreadDotFrame) / 2.0 ;
280+ _voiceUnreadDotImageView.frame = voiceUnreadDotFrame;
281+ }
282+
283+ #pragma mark - Life cycle
284+
255285- (instancetype )initWithFrame : (CGRect)frame
256286 message : (id <XHMessageModel>)message {
257287 self = [super initWithFrame: frame];
@@ -374,25 +404,30 @@ - (void)layoutSubviews {
374404 case XHBubbleMessageMediaTypeEmotion: {
375405 self.bubbleImageView .frame = bubbleFrame;
376406
377- CGFloat textX = CGRectGetMinX (bubbleFrame) + kBubblePaddingRight ;
407+ CGFloat textX = CGRectGetMinX (bubbleFrame) + kTextHorizontalBubblePadding ;
378408
379409 if (self.message .bubbleMessageType == XHBubbleMessageTypeReceiving) {
380410 textX += kXHArrowMarginWidth / 2.0 ;
381411 }
382412
383413 CGRect textFrame = CGRectMake (textX,
384- CGRectGetMinY (bubbleFrame) + kPaddingTop ,
385- CGRectGetWidth (bubbleFrame) - kBubblePaddingRight * 2 ,
386- bubbleFrame.size .height - kMarginTop - kMarginBottom );
414+ CGRectGetMinY (bubbleFrame) + kTextMarginTop ,
415+ CGRectGetWidth (bubbleFrame) - kTextHorizontalBubblePadding * 2 - kXHArrowMarginWidth / 2.0 ,
416+ bubbleFrame.size .height - kTextMarginTop - kTextMarginBottom );
387417
388418 self.displayTextView .frame = CGRectIntegral (textFrame);
389419
390420 CGRect animationVoiceImageViewFrame = self.animationVoiceImageView .frame ;
391- animationVoiceImageViewFrame.origin = CGPointMake ((self.message .bubbleMessageType == XHBubbleMessageTypeReceiving ? (bubbleFrame.origin .x + kVoiceMargin ) : (bubbleFrame.origin .x + CGRectGetWidth (bubbleFrame) - kVoiceMargin - CGRectGetWidth (animationVoiceImageViewFrame))), 17 );
421+ CGFloat voiceImagePaddingX = CGRectGetMaxX (bubbleFrame) - kVoiceMargin - CGRectGetWidth (animationVoiceImageViewFrame);
422+ if (self.message .bubbleMessageType == XHBubbleMessageTypeReceiving) {
423+ voiceImagePaddingX = CGRectGetMinX (bubbleFrame) + kVoiceMargin ;
424+ }
425+ animationVoiceImageViewFrame.origin = CGPointMake (voiceImagePaddingX,
426+ CGRectGetHeight (bubbleFrame) / 2.0 );
392427 self.animationVoiceImageView .frame = animationVoiceImageViewFrame;
393428
394- [self resetVoiceDurationLabelFrameWithBubbleFrame : bubbleFrame];
395- [self resetVoiceUnreadDotImageViewFrameWithBubbleFrame : bubbleFrame];
429+ [self configureVoiceDurationLabelFrameWithBubbleFrame : bubbleFrame];
430+ [self configureVoiceUnreadDotImageViewFrameWithBubbleFrame : bubbleFrame];
396431
397432 self.emotionImageView .frame = bubbleFrame;
398433
@@ -401,7 +436,7 @@ - (void)layoutSubviews {
401436 case XHBubbleMessageMediaTypePhoto:
402437 case XHBubbleMessageMediaTypeVideo:
403438 case XHBubbleMessageMediaTypeLocalPosition: {
404- CGRect photoImageViewFrame = CGRectMake (bubbleFrame.origin .x - 2 , 0 , bubbleFrame.size .width , bubbleFrame.size .height );
439+ CGRect photoImageViewFrame = CGRectMake (bubbleFrame.origin .x , 0 , bubbleFrame.size .width , bubbleFrame.size .height );
405440 self.bubblePhotoImageView .frame = photoImageViewFrame;
406441
407442 self.videoPlayImageView .center = CGPointMake (CGRectGetWidth (photoImageViewFrame) / 2.0 , CGRectGetHeight (photoImageViewFrame) / 2.0 );
@@ -416,19 +451,4 @@ - (void)layoutSubviews {
416451 }
417452}
418453
419- - (void )resetVoiceDurationLabelFrameWithBubbleFrame : (CGRect)bubbleFrame {
420- CGRect voiceFrame = _voiceDurationLabel.frame ;
421- voiceFrame.origin .x = (self.message .bubbleMessageType == XHBubbleMessageTypeSending ? bubbleFrame.origin .x - _voiceDurationLabel.frame .size .width : bubbleFrame.origin .x + bubbleFrame.size .width );
422- _voiceDurationLabel.frame = voiceFrame;
423-
424- _voiceDurationLabel.textAlignment = (self.message .bubbleMessageType == XHBubbleMessageTypeSending ? NSTextAlignmentRight : NSTextAlignmentLeft);
425- }
426-
427- - (void )resetVoiceUnreadDotImageViewFrameWithBubbleFrame : (CGRect)bubbleFrame {
428- CGRect voiceUnreadDotFrame = _voiceUnreadDotImageView.frame ;
429- voiceUnreadDotFrame.origin .x = (self.message .bubbleMessageType == XHBubbleMessageTypeSending ? bubbleFrame.origin .x + _voiceUnreadDotImageView.frame .size .width : bubbleFrame.origin .x + bubbleFrame.size .width - _voiceUnreadDotImageView.frame .size .width * 2 );
430- voiceUnreadDotFrame.origin .y = bubbleFrame.size .height /2 + _voiceUnreadDotImageView.frame .size .height /2 - 2 ;
431- _voiceUnreadDotImageView.frame = voiceUnreadDotFrame;
432- }
433-
434454@end
0 commit comments