首页 > 代码库 > [iOS基础控件 6.9.1] 聊天界面Demo 代码
[iOS基础控件 6.9.1] 聊天界面Demo 代码
框架:
所有代码文件:
Model:
1 // 2 // Message.h 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 // message信息模型,存储聊天记录 9 10 #import <Foundation/Foundation.h>11 12 typedef enum {13 MessageTypeMe = 0, // 我发出的信息14 MessageTypeOhter = 1 // 对方发出的信息15 } MessageType;16 17 @interface Message : NSObject18 19 /** 信息 */20 @property(nonatomic, copy) NSString *text;21 22 /** 发送时间 */23 @property(nonatomic, copy) NSString *time;24 25 /** 发送方 */26 @property(nonatomic, assign) MessageType type;27 28 /** 是否隐藏发送时间 */29 @property(nonatomic, assign) BOOL hideTime;30 31 - (instancetype) initWithDictionary:(NSDictionary *) dictionary;32 + (instancetype) messageWithDictionary:(NSDictionary *) dictionary;33 + (instancetype) message;34 35 @end
1 // 2 // Message.m 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "Message.h"10 11 @implementation Message12 13 - (instancetype) initWithDictionary:(NSDictionary *) dictionary {14 if (self = [super init]) {15 [self setValuesForKeysWithDictionary:dictionary];16 }17 18 return self;19 }20 21 + (instancetype) messageWithDictionary:(NSDictionary *) dictionary {22 return [[self alloc] initWithDictionary:dictionary];23 }24 25 + (instancetype) message {26 return [self messageWithDictionary:nil];27 }28 29 @end
1 // 2 // MessageFrame.h 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 // 存储每个cell内子控件的位置尺寸的frame 9 10 #import <Foundation/Foundation.h>11 #import <UIKit/UIKit.h>12 #import "Message.h"13 14 #define MESSAGE_TIME_FONT [UIFont systemFontOfSize:13]15 #define MESSAGE_TEXT_FONT [UIFont systemFontOfSize:15]16 #define TEXT_INSET 2017 18 @interface MessageFrame : NSObject19 20 /** 发送时间 */21 @property(nonatomic, assign, readonly) CGRect timeFrame;22 23 /** 头像 */24 @property(nonatomic, assign, readonly) CGRect iconFrame;25 26 /** 信息 */27 @property(nonatomic, assign, readonly) CGRect textFrame;28 29 /** 信息model */30 @property(nonatomic, strong) Message *message;31 32 /** cell的高度 */33 @property(nonatomic, assign) CGFloat cellHeight;34 35 36 @end
1 // 2 // MessageFrame.m 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "MessageFrame.h"10 #import "NSString+Extension.h"11 12 @implementation MessageFrame13 14 /** 设置message,计算位置尺寸 */15 - (void)setMessage:(Message *)message {16 _message = message;17 18 // 间隙19 CGFloat padding = 10;20 21 // 1.发送时间22 if (NO == message.hideTime) {23 CGFloat timeWidth = [UIScreen mainScreen].bounds.size.width;24 CGFloat timeHeight = 40;25 CGFloat timeX = 0;26 CGFloat timeY = 0;27 _timeFrame = CGRectMake(timeX, timeY, timeWidth, timeHeight);28 }29 30 // 2.头像31 CGFloat iconWidth = 40;32 CGFloat iconHeight = 40;33 34 // 2.1 根据信息的发送方调整头像位置35 CGFloat iconX;36 if (MessageTypeMe == message.type) {37 // 我方,放在右边38 iconX = [UIScreen mainScreen].bounds.size.width - padding - iconWidth;39 } else {40 // 对方,放在左边41 iconX = padding;42 }43 44 CGFloat iconY = CGRectGetMaxY(_timeFrame) + padding;45 _iconFrame = CGRectMake(iconX, iconY, iconWidth, iconHeight);46 47 // 3.信息,尺寸可变48 CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;49 // 3.1 设置文本最大尺寸50 CGSize textMaxSize = CGSizeMake(screenWidth - iconWidth - padding * 10, MAXFLOAT);51 // 3.2 计算文本真实尺寸52 CGSize textRealSize = [message.text sizeWithFont:MESSAGE_TEXT_FONT maxSize:textMaxSize];53 54 // 3.3 按钮尺寸55 CGSize btnSize = CGSizeMake(textRealSize.width + TEXT_INSET*2, textRealSize.height + TEXT_INSET*2);56 57 // 3.4 调整信息的位置58 CGFloat textX;59 if (MessageTypeMe == message.type) {60 // 我方,放在靠右61 textX = CGRectGetMinX(_iconFrame) - btnSize.width - padding;62 } else {63 // 对方,放在靠左64 textX = CGRectGetMaxX(_iconFrame) + padding;65 }66 67 CGFloat textY = iconY;68 _textFrame = CGRectMake(textX, textY, btnSize.width, btnSize.height);69 70 // 4.cell的高度71 CGFloat iconMaxY = CGRectGetMaxY(_iconFrame);72 CGFloat textMaxY = CGRectGetMaxY(_textFrame);73 _cellHeight = MAX(iconMaxY, textMaxY) + padding;74 }75 76 77 @end
View:
1 // 2 // MessageCell.h 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import <UIKit/UIKit.h>10 11 #define BACKGROUD_COLOR [UIColor colorWithRed:235/255.0 green:235/255.0 blue:235/255.0 alpha:1.0]12 13 @class MessageFrame, Message;14 15 @interface MessageCell : UITableViewCell16 17 /** 持有存储了聊天记录和聊天框位置尺寸的frame */18 @property(nonatomic, strong) MessageFrame *messageFrame;19 20 /** 传入父控件tableView引用的构造方法 */21 + (instancetype) cellWithTableView:(UITableView *) tableView;22 23 @end
1 // 2 // MessageCell.m 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "MessageCell.h" 10 #import "MessageFrame.h" 11 #import "UIImage+Extension.h" 12 13 @interface MessageCell() 14 15 // 定义cell内的子控件,用于保存控件,然后进行数据和位置尺寸的计算 16 /** 发送时间 */ 17 @property(nonatomic, weak) UILabel *timeLabel; 18 19 /** 头像 */ 20 @property(nonatomic, weak) UIImageView *iconView; 21 22 /** 信息 */ 23 @property(nonatomic, weak) UIButton *textView; 24 25 @end 26 27 @implementation MessageCell 28 29 - (void)awakeFromNib { 30 // Initialization code 31 } 32 33 - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 34 [super setSelected:selected animated:animated]; 35 36 // Configure the view for the selected state 37 } 38 39 #pragma mark - 构造方法 40 // 自定义构造方法 41 + (instancetype) cellWithTableView:(UITableView *) tableView { 42 static NSString *ID = @"message"; 43 44 // 使用缓存池 45 MessageCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; 46 47 // 创建一个新的cell 48 if (nil == cell) { 49 cell = [[MessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 50 } 51 52 return cell; 53 } 54 55 // 重写构造方法,创建cell中的各个子控件 56 - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 57 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 58 59 // 设置cell的背景色 60 self.backgroundColor = BACKGROUD_COLOR; 61 62 // 1.发送时间 63 UILabel *timeLabel = [[UILabel alloc] init]; 64 [timeLabel setTextAlignment:NSTextAlignmentCenter]; 65 [timeLabel setFont:MESSAGE_TIME_FONT]; 66 [timeLabel setTextColor:[UIColor grayColor]]; 67 [self.contentView addSubview:timeLabel]; 68 self.timeLabel = timeLabel; 69 70 // 2.头像 71 UIImageView *iconView = [[UIImageView alloc] init]; 72 [self.contentView addSubview:iconView]; 73 self.iconView = iconView; 74 75 // 3.信息 76 UIButton *textView = [[UIButton alloc] init]; 77 [textView setTitle:@"text" forState:UIControlStateNormal]; 78 [textView.titleLabel setFont:MESSAGE_TEXT_FONT]; 79 80 // 3.1 如果是浅色背景,记得设置字体颜色,因为按钮的字体颜色默认是白色 81 [textView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; 82 [textView.titleLabel setNumberOfLines:0]; // 设置自动换行 83 84 // 3.2 调整文字的内边距 85 textView.contentEdgeInsets = UIEdgeInsetsMake(TEXT_INSET, TEXT_INSET, TEXT_INSET, TEXT_INSET); 86 87 [self.contentView addSubview:textView]; 88 self.textView = textView; 89 90 return self; 91 } 92 93 #pragma mark - 加载数据 94 // 加载frame,初始化cell中子控件的数据、位置尺寸 95 - (void)setMessageFrame:(MessageFrame *) messageFrame { 96 _messageFrame = messageFrame; 97 98 // 1.发送时间 99 self.timeLabel.text = messageFrame.message.time;100 self.timeLabel.frame = messageFrame.timeFrame;101 102 // 2.头像103 NSString *icon = (messageFrame.message.type == MessageTypeMe)? @"me":@"other";104 self.iconView.image = [UIImage imageNamed:icon];105 self.iconView.frame = messageFrame.iconFrame;106 107 // 3.信息108 [self.textView setTitle:messageFrame.message.text forState:UIControlStateNormal];109 self.textView.frame = messageFrame.textFrame;110 111 // 3.1 设置聊天框112 NSString *chatImageNormalName;113 NSString *chatImageHighlightedName;114 if (MessageTypeMe == messageFrame.message.type) {115 chatImageNormalName = @"chat_send_nor";116 chatImageHighlightedName = @"chat_send_press_pic";117 } else {118 chatImageNormalName = @"chat_receive_nor";119 chatImageHighlightedName = @"chat_receive_press_pic";120 }121 122 UIImage *chatImageNormal = [UIImage resizableImage:chatImageNormalName];123 UIImage *chatImageHighlighted = [UIImage resizableImage:chatImageHighlightedName];124 [self.textView setBackgroundImage:chatImageNormal forState:UIControlStateNormal];125 [self.textView setBackgroundImage:chatImageHighlighted forState:UIControlStateHighlighted];126 }127 128 129 @end
Controller:
1 // 2 // ViewController.m 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "Message.h" 11 #import "MessageCell.h" 12 #import "MessageFrame.h" 13 14 @interface ViewController () <UITableViewDataSource, UITableViewDelegate, UITextFieldDelegate> 15 16 /** 聊天区tableView */ 17 @property (weak, nonatomic) IBOutlet UITableView *tableView; 18 19 /** 信息记录数据 */ 20 @property(nonatomic, strong) NSMutableArray *messages; 21 22 /** 信息输入框 */ 23 @property (weak, nonatomic) IBOutlet UITextField *inputView; 24 25 @end 26 27 @implementation ViewController 28 29 - (void)viewDidLoad { 30 [super viewDidLoad]; 31 // Do any additional setup after loading the view, typically from a nib. 32 33 // 设置dataSource 34 self.tableView.dataSource = self; 35 36 // 设置tableView的delegate 37 self.tableView.delegate = self; 38 39 // 设置tableView背景色,当键盘呼出隐藏的时候,避免默认的黑色背景出现太突兀 40 self.tableView.backgroundColor = BACKGROUD_COLOR; 41 42 // 设置聊天区TableView 43 // 不使用分割线 44 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 45 // 禁止选中cell 46 [self.tableView setAllowsSelection:NO]; 47 48 // 设置虚拟键盘监听器 49 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil]; 50 51 // 设置TextField文字左间距 52 self.inputView.leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 8, 0)]; 53 self.inputView.leftViewMode = UITextFieldViewModeAlways; 54 55 // 设置信息输入框的代理 56 self.inputView.delegate = self; 57 } 58 59 - (void)didReceiveMemoryWarning { 60 [super didReceiveMemoryWarning]; 61 // Dispose of any resources that can be recreated. 62 } 63 64 - (BOOL)prefersStatusBarHidden { 65 return YES; 66 } 67 68 #pragma mark - 数据加载 69 /** 延迟加载plist文件数据 */ 70 - (NSMutableArray *)messages { 71 if (nil == _messages) { 72 NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"messages.plist" ofType:nil]]; 73 74 NSMutableArray *mdictArray = [NSMutableArray array]; 75 for (NSDictionary *dict in dictArray) { 76 Message *message = [Message messageWithDictionary:dict]; 77 78 // 判断是否发送时间与上一条信息的发送时间相同,若是则不用显示了 79 MessageFrame *lastMessageFrame = [mdictArray lastObject]; 80 if (lastMessageFrame && [message.time isEqualToString:lastMessageFrame.message.time]) { 81 message.hideTime = YES; 82 } 83 84 MessageFrame *messageFrame = [[MessageFrame alloc] init]; 85 messageFrame.message = message; 86 [mdictArray addObject:messageFrame]; 87 } 88 89 _messages = mdictArray; 90 } 91 92 return _messages; 93 } 94 95 #pragma mark - dataSource方法 96 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 97 return self.messages.count; 98 } 99 100 - (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {101 MessageCell *cell = [MessageCell cellWithTableView:self.tableView];102 cell.messageFrame = self.messages[indexPath.row];103 104 return cell;105 }106 107 108 #pragma mark - tableView代理方法109 /** 动态设置每个cell的高度 */110 - (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {111 MessageFrame *messageFrame = self.messages[indexPath.row];112 return messageFrame.cellHeight;113 }114 115 #pragma mark - scrollView 代理方法116 /** 点击拖曳聊天区的时候,缩回键盘 */117 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {118 // 1.缩回键盘119 [self.view endEditing:YES];120 }121 122 123 #pragma mark - 监听事件124 - (void) keyboardWillChangeFrame:(NSNotification *) note {125 // 1.取得弹出后的键盘frame126 CGRect keyboardFrame = [note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];127 128 // 2.键盘弹出的耗时时间129 CGFloat duration = [note.userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];130 131 // 3.键盘变化时,view的位移,包括了上移/恢复下移132 CGFloat transformY = keyboardFrame.origin.y - self.view.frame.size.height;133 134 [UIView animateWithDuration:duration animations:^{135 self.view.transform = CGAffineTransformMakeTranslation(0, transformY);136 }];137 }138 139 #pragma mark - TextField 代理方法140 /** 回车响应事件 */141 - (BOOL)textFieldShouldReturn:(UITextField *)textField {142 // 我方发出信息143 [self sendMessageWithContent:textField.text andType:MessageTypeMe];144 145 // 自动回复146 [self sendMessageWithContent:[NSString stringWithFormat:@"%@\n%@", textField.text, @"你妹!!!"] andType:MessageTypeOhter];147 148 // 消除消息框内容149 self.inputView.text = nil;150 151 [self.tableView reloadData];152 153 // 滚动到最新的消息154 NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:self.messages.count - 1 inSection:0];155 [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];156 157 return YES; // 返回值意义不明158 }159 160 // 发送消息161 - (void) sendMessageWithContent:(NSString *) text andType:(MessageType) type {162 // 获取当前时间163 NSDate *date = [NSDate date];164 NSDateFormatter *formatter = [[NSDateFormatter alloc] init];165 formatter.dateFormat = @"yyyy-MMM-dd hh:mm:ss";166 NSString *dateStr = [formatter stringFromDate:date];167 168 // 我方发出信息169 NSDictionary *dict = @{@"text":text,170 @"time":dateStr,171 @"type":[NSString stringWithFormat:@"%d", type]};172 173 Message *message = [[Message alloc] init];174 [message setValuesForKeysWithDictionary:dict];175 MessageFrame *messageFrame = [[MessageFrame alloc] init];176 messageFrame.message = message;177 178 [self.messages addObject:messageFrame];179 }180 181 @end182
工具类:
1 // 2 // NSString+Extension.h 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 // NSString扩展类 9 10 #import <Foundation/Foundation.h>11 #import <UIKit/UIKit.h>12 13 @interface NSString (Extension)14 15 /** 测量文本的尺寸 */16 - (CGSize) sizeWithFont:(UIFont *)font maxSize:(CGSize) maxSize;17 18 @end
1 // 2 // NSString+Extension.m 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "NSString+Extension.h"10 11 @implementation NSString (Extension)12 13 /** 测量文本的尺寸 */14 - (CGSize)sizeWithFont:(UIFont *)font maxSize:(CGSize)maxSize {15 NSDictionary *attrs = @{NSFontAttributeName: font};16 CGSize size = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;17 18 return size;19 }20 21 @end
1 // 2 // UIImage+Extension.h 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 // NSImage 类的扩展 9 10 #import <Foundation/Foundation.h>11 #import <UIKit/UIKit.h>12 13 @interface UIImage (Extension)14 15 + (UIImage *) resizableImage:(NSString *) imageName;16 17 @end18
1 // 2 // UIImage+Extension.m 3 // QQChatDemo 4 // 5 // Created by hellovoidworld on 14/12/8. 6 // Copyright (c) 2014年 hellovoidworld. All rights reserved. 7 // 8 9 #import "UIImage+Extension.h"10 11 @implementation UIImage (Extension)12 13 + (UIImage *) resizableImage:(NSString *) imageName {14 UIImage *image = [UIImage imageNamed:imageName];15 // 取图片中部的1 x 1进行拉伸16 UIEdgeInsets insets = UIEdgeInsetsMake(image.size.height/2, image.size.width/2, image.size.height/2 + 1, image.size.width/2 + 1);17 return [image resizableImageWithCapInsets:insets];18 }19 20 @end
[iOS基础控件 6.9.1] 聊天界面Demo 代码
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。