020606-07-聊天布局
// XMGChatingViewController.m // 07-聊天布局 #import "XMGChatingViewController.h" #import "XMGMessage.h" #import "XMGMessageCell.h" //#import "XMGMeCell.h" //#import "XMGOtherCell.h" @interface XMGChatingViewController () <UITableViewDataSource, UITableViewDelegate> @property (nonatomic, strong) NSArray *messages; @property (weak, nonatomic) IBOutlet UITextField *messageField; @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; } - (void)viewDidLoad { [super viewDidLoad]; // 设置文本框左边的内容 UIView *leftView = [[UIView alloc] init]; leftView.frame = CGRectMake(0, 0, 10, 0); self.messageField.leftView = leftView; self.messageField.leftViewMode = UITextFieldViewModeAlways; // 监听键盘通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } #pragma mark - 键盘处理 - (void)keyboardWillChangeFrame:(NSNotification *)note { // 取出键盘最终的frame CGRect rect = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; // 取出键盘弹出需要花费的时间 double duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; // 修改transform [UIView animateWithDuration:duration animations:^{ CGFloat ty = [UIScreen mainScreen].bounds.size.height - rect.origin.y; self.view.transform = CGAffineTransformMakeTranslation(0, - ty); }]; } #pragma mark - <UITableViewDataSource> - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.messages.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { // 取出模型 XMGMessage *msg = self.messages[indexPath.row]; // 重用标识(决定了cell的类型) NSString *ID = (msg.type == XMGMessageTypeMe) ? @"me" : @"other"; // 加载cell XMGMessageCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; cell.message = msg; return cell; // if (msg.type == XMGMessageTypeMe) { // static NSString *ID = @"me"; // // 加载cell // XMGMeCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // // cell.message = msg; // // return cell; // } else { // static NSString *ID = @"other"; // // 加载cell // XMGOtherCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; // // cell.message = msg; // // 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; } - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { // 退出键盘 // [self.messageField resignFirstResponder]; // [self.messageField endEditing:YES]; [self.view endEditing:YES]; } @end
// XMGMessageCell.h // 07-聊天布局 #import <UIKit/UIKit.h> @class XMGMessage; @interface XMGMessageCell : UITableViewCell @property (nonatomic, strong) XMGMessage *message; @end
// XMGMessageCell.m // 07-聊天布局 #import "XMGMessageCell.h" #import "XMGMessage.h" //define this constant if you want to use Masonry without the 'mas_' prefix #define MAS_SHORTHAND //define this constant if you want to enable auto-boxing for default syntax #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
// XMGMeCell.h // 07-聊天布局 #import <UIKit/UIKit.h> @class XMGMessage; @interface XMGMeCell : UITableViewCell @property (nonatomic, strong) XMGMessage *message; @end
// XMGMeCell.m // 07-聊天布局 #import "XMGMeCell.h" #import "XMGMessage.h" //define this constant if you want to use Masonry without the 'mas_' prefix #define MAS_SHORTHAND //define this constant if you want to enable auto-boxing for default syntax #define MAS_SHORTHAND_GLOBALS #import "Masonry.h" @interface XMGMeCell() @property (weak, nonatomic) IBOutlet UILabel *timeLabel; @property (weak, nonatomic) IBOutlet UIButton *textButton; @property (weak, nonatomic) IBOutlet UIImageView *iconView; @end @implementation XMGMeCell - (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.textButton layoutIfNeeded]; // 设置按钮的高度就是titleLabel的高度 [self.textButton updateConstraints:^(MASConstraintMaker *make) { CGFloat buttonH = self.textButton.titleLabel.frame.size.height + 30; make.height.equalTo(buttonH); }]; // 强制更新 [self.textButton layoutIfNeeded]; // 计算当前cell的高度 CGFloat buttonMaxY = CGRectGetMaxY(self.textButton.frame); CGFloat iconMaxY = CGRectGetMaxY(self.iconView.frame); self.message.cellHeight = MAX(buttonMaxY, iconMaxY) + 10; } @end
// XMGOtherCell.h // 07-聊天布局 #import <UIKit/UIKit.h> @class XMGMessage; @interface XMGOtherCell : UITableViewCell @property (nonatomic, strong) XMGMessage *message; @end
// XMGOtherCell.m // 07-聊天布 #import "XMGOtherCell.h" #import "XMGMessage.h" //define this constant if you want to use Masonry without the 'mas_' prefix #define MAS_SHORTHAND //define this constant if you want to enable auto-boxing for default syntax #define MAS_SHORTHAND_GLOBALS #import "Masonry.h" @interface XMGOtherCell() @property (weak, nonatomic) IBOutlet UILabel *timeLabel; @property (weak, nonatomic) IBOutlet UIButton *textButton; @property (weak, nonatomic) IBOutlet UIImageView *iconView; @end @implementation XMGOtherCell - (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.textButton layoutIfNeeded]; // 设置按钮的高度就是titleLabel的高度 [self.textButton updateConstraints:^(MASConstraintMaker *make) { CGFloat buttonH = self.textButton.titleLabel.frame.size.height + 30; make.height.equalTo(buttonH); }]; // 强制更新 [self.textButton layoutIfNeeded]; // 计算当前cell的高度 CGFloat buttonMaxY = CGRectGetMaxY(self.textButton.frame); CGFloat iconMaxY = CGRectGetMaxY(self.iconView.frame); self.message.cellHeight = MAX(buttonMaxY, iconMaxY) + 10; } @end
// XMGMessage.h // 07-聊天布局 #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
// XMGMessage.m // 07-聊天布局 #import "XMGMessage.h" @implementation XMGMessage + (instancetype)messageWithDict:(NSDictionary *)dict { XMGMessage *message = [[self alloc] init]; [message setValuesForKeysWithDictionary:dict]; return message; } @end
本人无商业用途,仅仅是学习做个笔记,特别鸣谢小马哥,学习了IOS,另日语学习内容有需要文本和音频请关注公众号:riyuxuexishuji