iOS开发_UITableView聊天布局

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 布局
    • 多 Cell 布局
  • 3.2 设置气泡图片拉伸

  • 3.3 设置按钮边距

4、XMGMessageCell.h

#import <UIKit/UIKit.h>

@class XMGMessage;

@interface XMGMessageCell : UITableViewCell

@property (nonatomic, strong) XMGMessage *message;

@end

5、XMGMessageCell.m

  • 5.1 单 Cell 布局

#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
  • 5.2 多 Cell 布局

#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、效果

posted @ 2018-08-05 12:51  CH520  阅读(324)  评论(0编辑  收藏  举报