1、XMGMessage.h
#import <UIKit/UIKit.h>
typedef enum {
XMGMessageTypeMe = 0,
XMGMessageTypeOther = 1
} XMGMessageType;
@interface XMGMessage : NSObject
@property (nonatomic, strong) NSString *text;
@property (nonatomic, strong) NSString *time;
@property (nonatomic, assign) XMGMessageType type;
/** cell 的高度 */
@property (nonatomic, assign) CGFloat cellHeight;
/** 是否隐藏时间 */
@property (nonatomic, assign, getter=isHideTime) BOOL hideTime;
+ (instancetype)messageWithDict:(NSDictionary *)dict;
@end
2、XMGMessage.m
#import "XMGMessage.h"
@implementation XMGMessage
+ (instancetype)messageWithDict:(NSDictionary *)dict {
XMGMessage *message = [[self alloc] init];
[message setValuesForKeysWithDictionary:dict];
return message;
}
@end
3、Main.storyboard
3.1 设置 cell
- 单 Cell 布局
![1213778-20180805123548706-2125918935.png](https://i-blog.csdnimg.cn/blog_migrate/0add30084a2c60cce29459d4f2874487.png)
- 多 Cell 布局
![1213778-20180805123553033-1866961636.png](https://i-blog.csdnimg.cn/blog_migrate/5f3987749453bf55fd0c01535f5b209b.png)
3.2 设置气泡图片拉伸
![1213778-20180805123559665-390930932.png](https://i-blog.csdnimg.cn/blog_migrate/19aa28571c266624f8a1fef1a1b47757.png)
3.3 设置按钮边距
![1213778-20180805123603215-861000699.png](https://i-blog.csdnimg.cn/blog_migrate/eb827eccaa47ee08692ac43ebc7eca07.png)
4、XMGMessageCell.h
#import <UIKit/UIKit.h>
@class XMGMessage;
@interface XMGMessageCell : UITableViewCell
@property (nonatomic, strong) XMGMessage *message;
@end
5、XMGMessageCell.m
#import "XMGMessageCell.h"
#import "XMGMessage.h"
#define MAS_SHORTHAND
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"
@interface XMGMessageCell()
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
@property (weak, nonatomic) IBOutlet UIButton *textButton;
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UIButton *otherTextButton;
@property (weak, nonatomic) IBOutlet UIImageView *otherIconView;
@end
@implementation XMGMessageCell
- (void)awakeFromNib {
self.textButton.titleLabel.numberOfLines = 0;
self.otherTextButton.titleLabel.numberOfLines = 0;
}
- (void)setMessage:(XMGMessage *)message {
_message = message;
if (message.hideTime) { // 隐藏时间
self.timeLabel.hidden = YES;
[self.timeLabel updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(0);
}];
} else { // 显示时间
self.timeLabel.text = message.time;
self.timeLabel.hidden = NO;
[self.timeLabel updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(21);
}];
}
// 强制更新
[self layoutIfNeeded];
if (message.type == XMGMessageTypeMe) { // 右边
[self settingShowTextButton:self.textButton
showIconView:self.iconView
hideTextButton:self.otherTextButton
hideIconView:self.otherIconView];
} else { // 左边
[self settingShowTextButton:self.otherTextButton
showIconView:self.otherIconView
hideTextButton:self.textButton
hideIconView:self.iconView];
}
}
/**
* 处理左右按钮、头像
*/
- (void)settingShowTextButton:(UIButton *)showTextButton showIconView:(UIImageView *)showIconView hideTextButton:(UIButton *)hideTextButton
hideIconView:(UIImageView *)hideIconView {
hideTextButton.hidden = YES;
hideIconView.hidden = YES;
showTextButton.hidden = NO;
showIconView.hidden = NO;
// 设置按钮的文字
[showTextButton setTitle:self.message.text forState:UIControlStateNormal];
// 强制更新
[showTextButton layoutIfNeeded];
// 设置按钮的高度就是titleLabel的高度
[showTextButton updateConstraints:^(MASConstraintMaker *make) {
CGFloat buttonH = showTextButton.titleLabel.frame.size.height + 30;
make.height.equalTo(buttonH);
}];
// 强制更新
[showTextButton layoutIfNeeded];
// 计算当前 cell 的高度
CGFloat buttonMaxY = CGRectGetMaxY(showTextButton.frame);
CGFloat iconMaxY = CGRectGetMaxY(showIconView.frame);
self.message.cellHeight = MAX(buttonMaxY, iconMaxY) + 10;
}
@end
#import "XMGMessageCell.h"
#import "XMGMessage.h"
#define MAS_SHORTHAND
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"
@interface XMGMessageCell()
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
@property (weak, nonatomic) IBOutlet UIButton *textButton;
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@end
@implementation XMGMessageCell
- (void)awakeFromNib {
self.textButton.titleLabel.numberOfLines = 0;
}
- (void)setMessage:(XMGMessage *)message {
_message = message;
// 时间处理
if (message.hideTime) { // 隐藏时间
self.timeLabel.hidden = YES;
[self.timeLabel updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(0);
}];
} else { // 显示时间
self.timeLabel.text = message.time;
self.timeLabel.hidden = NO;
[self.timeLabel updateConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(21);
}];
}
// 处理显示的消息文字
// 设置按钮的文字
[self.textButton setTitle:self.message.text forState:UIControlStateNormal];
// 强制更新
[self layoutIfNeeded];
// 设置按钮的高度就是titleLabel的高度
[self.textButton updateConstraints:^(MASConstraintMaker *make) {
CGFloat buttonH = self.textButton.titleLabel.frame.size.height + 30;
make.height.equalTo(buttonH);
}];
// 强制更新
[self layoutIfNeeded];
// 计算当前cell的高度
CGFloat buttonMaxY = CGRectGetMaxY(self.textButton.frame);
CGFloat iconMaxY = CGRectGetMaxY(self.iconView.frame);
self.message.cellHeight = MAX(buttonMaxY, iconMaxY) + 10;
}
@end
6、XMGChatingViewController.m
#import "XMGChatingViewController.h"
#import "XMGMessage.h"
#import "XMGMessageCell.h"
@interface XMGChatingViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) NSArray *messages;
@end
@implementation XMGChatingViewController
- (NSArray *)messages {
if (_messages == nil) {
// 加载plist中的字典数组
NSString *path = [[NSBundle mainBundle] pathForResource:@"messages.plist" ofType:nil];
NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
// 字典数组 -> 模型数组
NSMutableArray *messageArray = [NSMutableArray array];
// 用来记录上一条消息模型
XMGMessage *lastMessage = nil;
for (NSDictionary *dict in dictArray) {
XMGMessage *message = [XMGMessage messageWithDict:dict];
//埋下伏笔,加载数据时,判断哪个时间值相等。
message.hideTime = [message.time isEqualToString:lastMessage.time];
[messageArray addObject:message];
lastMessage = message;
}
_messages = messageArray;
}
return _messages;
}
#pragma mark - <UITableViewDataSource>
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.messages.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
XMGMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:@"message"];
cell.message = self.messages[indexPath.row];
return cell;
}
#pragma mark - <UITableViewDelegate>
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 200;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
XMGMessage *message = self.messages[indexPath.row];
return message.cellHeight;
}
@end
7、效果