首页 > 代码库 > qq聊天布局思路
qq聊天布局思路
qq聊天布局思路
步骤一、更改控制器继承UITableViewController,然后修改storyboard中的控制器。
步骤二、加载plist文件,创建对应的数据模型
+ (instancetype)qqWithDict:(NSDictionary *)dict
{
return [[selfalloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict
{
self = [superinit];
if (self) {
[selfsetValuesForKeysWithDictionary:dict];
}
return self;
}
步骤三、把数据模型用数组保存起来
+ (NSMutableArray *)qqs
{
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"messages.plist"ofType:nil]];
NSMutableArray *arrayM = [NSMutableArray array];
for (NSDictionary *dictin array) {
[arrayM addObject:[selfqqWithDict:dict]];
}
return arrayM;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@,%p>{text:%@,time:%@,type:%d}",self.class,self,self.text,self.time,self.type];
}
步骤四、把cell封装到View层里面,重写set方法,把frame计算好
+ (instancetype)qqView:(UITableView *)tableView
{
static NSString *ID =@"cell";
SUNQQView *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell ==nil) {
cell = [[SUNQQView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
return cell;
}
- (void)setQqInfo:(SUNQQInfo *)qqInfo
{
_qqInfo = qqInfo;
// 设置时间
self.timerLabel.text = qqInfo.time;
CGFloat timerW = [UIScreen mainScreen].bounds.size.width;
self.timerLabel.frame = CGRectMake(0,0, timerW,35);
// 设置头像
if (qqInfo.type) {
CGFloat imageX = kMargin;
CGFloat imageY = CGRectGetMaxY(self.timerLabel.frame) + kMargin;
self.iconImageView.frame = CGRectMake(imageX, imageY, kIconW, kIconH);
self.iconImageView.image = [UIImage imageNamed:@"other"];
}else{
CGFloat X = [UIScreen mainScreen].bounds.size.width - kMargin - kIconW;
CGFloat Y = CGRectGetMaxY(self.timerLabel.frame) +10;
self.iconImageView.frame = CGRectMake(X, Y, kIconW, kIconH);
self.iconImageView.image = [UIImage imageNamed:@"me"];
}
// 设置文字
NSDictionary *dict = @{NSFontAttributeName: [UIFont systemFontOfSize:13.0]};
CGRect frameText = [qqInfo.text boundingRectWithSize:CGSizeMake(150,MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];
[self.textBtn setTitle:qqInfo.text forState:UIControlStateNormal];
self.textBtn.contentEdgeInsets = UIEdgeInsetsMake(20,20,20,20);
CGFloat textY = CGRectGetMaxY(self.timerLabel.frame) +10;
CGFloat textW = frameText.size.width + 40;
CGFloat textH = frameText.size.height + 40;
CGFloat textX;
if (qqInfo.type) {
textX = CGRectGetMaxX(self.iconImageView.frame) +10;
}else{
textX = [UIScreen mainScreen].bounds.size.width - 2*kMargin - kIconW - textW;
}
self.textBtn.frame = CGRectMake(textX, textY, textW, textH);
// 设置行高
CGFloat maxH = MAX(CGRectGetMaxY(self.iconImageView.frame), CGRectGetMaxY(self.textBtn.frame));
self.cellHight = maxH + kMargin;
// 设置聊天背景
if (qqInfo.type) {
UIImage *image = [UIImage imageNamed:@"chat_recive_nor"];
UIImage *image1 = [image stretchableImageWithLeftCapWidth:30 topCapHeight:30];
[self.textBtn setBackgroundImage:image1 forState:UIControlStateNormal];
[self.textBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
}else{
UIImage *image = [UIImage imageNamed:@"chat_send_nor"];
UIImage *image1 = [image stretchableImageWithLeftCapWidth:30topCapHeight:30];
[self.textBtn setBackgroundImage:image1 forState:UIControlStateNormal];
[self.textBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
}
注意:
步骤二、加载plist文件,创建对应的数据模型
+ (instancetype)qqWithDict:(NSDictionary *)dict
{
return [[selfalloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict
{
self = [superinit];
if (self) {
[selfsetValuesForKeysWithDictionary:dict];
}
return self;
}
步骤三、把数据模型用数组保存起来
+ (NSMutableArray *)qqs
{
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"messages.plist"ofType:nil]];
NSMutableArray *arrayM = [NSMutableArray array];
for (NSDictionary *dictin array) {
[arrayM addObject:[selfqqWithDict:dict]];
}
return arrayM;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@,%p>{text:%@,time:%@,type:%d}",self.class,self,self.text,self.time,self.type];
}
步骤四、把cell封装到View层里面,重写set方法,把frame计算好
+ (instancetype)qqView:(UITableView *)tableView
{
static NSString *ID =@"cell";
SUNQQView *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell ==nil) {
cell = [[SUNQQView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
return cell;
}
- (void)setQqInfo:(SUNQQInfo *)qqInfo
{
_qqInfo = qqInfo;
// 设置时间
self.timerLabel.text = qqInfo.time;
CGFloat timerW = [UIScreen mainScreen].bounds.size.width;
self.timerLabel.frame = CGRectMake(0,0, timerW,35);
// 设置头像
if (qqInfo.type) {
CGFloat imageX = kMargin;
CGFloat imageY = CGRectGetMaxY(self.timerLabel.frame) + kMargin;
self.iconImageView.frame = CGRectMake(imageX, imageY, kIconW, kIconH);
self.iconImageView.image = [UIImage imageNamed:@"other"];
}else{
CGFloat X = [UIScreen mainScreen].bounds.size.width - kMargin - kIconW;
CGFloat Y = CGRectGetMaxY(self.timerLabel.frame) +10;
self.iconImageView.frame = CGRectMake(X, Y, kIconW, kIconH);
self.iconImageView.image = [UIImage imageNamed:@"me"];
}
// 设置文字
NSDictionary *dict = @{NSFontAttributeName: [UIFont systemFontOfSize:13.0]};
CGRect frameText = [qqInfo.text boundingRectWithSize:CGSizeMake(150,MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];
[self.textBtn setTitle:qqInfo.text forState:UIControlStateNormal];
self.textBtn.contentEdgeInsets = UIEdgeInsetsMake(20,20,20,20);
CGFloat textY = CGRectGetMaxY(self.timerLabel.frame) +10;
CGFloat textW = frameText.size.width + 40;
CGFloat textH = frameText.size.height + 40;
CGFloat textX;
if (qqInfo.type) {
textX = CGRectGetMaxX(self.iconImageView.frame) +10;
}else{
textX = [UIScreen mainScreen].bounds.size.width - 2*kMargin - kIconW - textW;
}
self.textBtn.frame = CGRectMake(textX, textY, textW, textH);
// 设置行高
CGFloat maxH = MAX(CGRectGetMaxY(self.iconImageView.frame), CGRectGetMaxY(self.textBtn.frame));
self.cellHight = maxH + kMargin;
// 设置聊天背景
if (qqInfo.type) {
UIImage *image = [UIImage imageNamed:@"chat_recive_nor"];
UIImage *image1 = [image stretchableImageWithLeftCapWidth:30 topCapHeight:30];
[self.textBtn setBackgroundImage:image1 forState:UIControlStateNormal];
[self.textBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
}else{
UIImage *image = [UIImage imageNamed:@"chat_send_nor"];
UIImage *image1 = [image stretchableImageWithLeftCapWidth:30topCapHeight:30];
[self.textBtn setBackgroundImage:image1 forState:UIControlStateNormal];
[self.textBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
}
注意:
1.在设置内容文字的自适应宽高,可以调用boundingRectWithSize方法
NSDictionary *dict = @{NSFontAttributeName: [UIFont systemFontOfSize:13.0]};
CGRect frameText = [qqInfo.text boundingRectWithSize:CGSizeMake(150,MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];
NSDictionary *dict = @{NSFontAttributeName: [UIFont systemFontOfSize:13.0]};
CGRect frameText = [qqInfo.text boundingRectWithSize:CGSizeMake(150,MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil];
2.按钮的宽度和高度,根据内容决定的,如果想更改按钮的宽度和高度,我们只需要修改内容的宽度和高度,但是加宽了按钮,按钮内部的宽度也会加宽,如果想要内容的宽度保持不变,需要设置按钮的内边距。
contentEdgeInsets
contentEdgeInsets
步骤五、实现其代理方法
#pragma mark -实现代理的方法- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath
{
SUNQQView *qqView = [[SUNQQViewalloc]init];
qqView.qqInfo= self.qqs[indexPath.row];
return qqView.cellHight;
}
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
SUNQQView *cell = [SUNQQViewqqView:tableView];
// 取出数据
cell.qqInfo= self.qqs[indexPath.row];
cell.backgroundColor= [UIColorclearColor];
return cell;
}
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
return self.qqs.count;
}
步骤六、监听键盘的通知
//监听键盘的通知
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(keyboardWillChangeFrame:)name:UIKeyboardWillChangeFrameNotificationobject:nil];
[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(keyboardWillChangeFrame:)name:UIKeyboardWillChangeFrameNotificationobject:nil];
- (void)keyboardWillChangeFrame:(NSNotification*)noti
{
NSLog(@"%@",noti.userInfo);
// 设置窗口的颜色
self.view.window.backgroundColor= self.tableView.backgroundColor;
// 取出键盘动画的时间
CGFloat duration= [noti.userInfo[UIKeyboardAnimationDurationUserInfoKey]doubleValue];
// 取得键盘最后的frame
CGRect keyboardFrame = [noti.userInfo[UIKeyboardFrameEndUserInfoKey]CGRectValue];
// 计算控制器移动的距离
CGFloat tansformY = keyboardFrame.origin.y- self.view.frame.size.height;
// 执行动画
[UIViewanimateWithDuration:durationanimations:^{
self.view.transform= CGAffineTransformMakeTranslation(0, tansformY);
}];
}
// 移除通知
- (void)dealloc
{
[[NSNotificationCenterdefaultCenter]removeObserver:self];
}
{
NSLog(@"%@",noti.userInfo);
// 设置窗口的颜色
self.view.window.backgroundColor= self.tableView.backgroundColor;
// 取出键盘动画的时间
CGFloat duration= [noti.userInfo[UIKeyboardAnimationDurationUserInfoKey]doubleValue];
// 取得键盘最后的frame
CGRect keyboardFrame = [noti.userInfo[UIKeyboardFrameEndUserInfoKey]CGRectValue];
// 计算控制器移动的距离
CGFloat tansformY = keyboardFrame.origin.y- self.view.frame.size.height;
// 执行动画
[UIViewanimateWithDuration:durationanimations:^{
self.view.transform= CGAffineTransformMakeTranslation(0, tansformY);
}];
}
// 移除通知
- (void)dealloc
{
[[NSNotificationCenterdefaultCenter]removeObserver:self];
}
步骤七、自动回复- (void)addMessage:(NSString*)text type:(MJMessageType)type
{
// 1.数据模型
MJMessage *msg = [[MJMessagealloc]init];
msg.type= type;
msg.text= text;
// 设置数据模型的时间
NSDate *now = [NSDatedate];
NSDateFormatter *fmt = [[NSDateFormatteralloc]init];
fmt.dateFormat= @"HH:mm";
msg.time= [fmt stringFromDate:now];
// 看是否需要隐藏时间
MJMessageFrame *lastMf = [self.messageFrameslastObject];
MJMessage *lastMsg = lastMf.message;
msg.hideTime= [msg.timeisEqualToString:lastMsg.time];
// 2.frame模型
MJMessageFrame *mf = [[MJMessageFramealloc]init];
mf.message= msg;
[self.messageFramesaddObject:mf];
//
[self.tableViewreloadData];
// 4.自动滚动表格到最后一行
NSIndexPath *lastPath = [NSIndexPathindexPathForRow:self.messageFrames.count- 1 inSection:0];
[self.tableViewscrollToRowAtIndexPath:lastPathatScrollPosition:UITableViewScrollPositionBottomanimated:YES];
}
/**
* 根据自己发的内容取得自动回复的内容
*
* @param text 自己发的内容
*/
- (NSString*)replayWithText:(NSString*)text
{
for (inti = 0; i<text.length; i++) {
NSString *word = [textsubstringWithRange:NSMakeRange(i,1)];
if (self.autoreply[word])return self.autoreply[word];
}
return @"滚蛋";
}
// 1.数据模型
MJMessage *msg = [[MJMessagealloc]init];
msg.type= type;
msg.text= text;
// 设置数据模型的时间
NSDate *now = [NSDatedate];
NSDateFormatter *fmt = [[NSDateFormatteralloc]init];
fmt.dateFormat= @"HH:mm";
msg.time= [fmt stringFromDate:now];
// 看是否需要隐藏时间
MJMessageFrame *lastMf = [self.messageFrameslastObject];
MJMessage *lastMsg = lastMf.message;
msg.hideTime= [msg.timeisEqualToString:lastMsg.time];
// 2.frame模型
MJMessageFrame *mf = [[MJMessageFramealloc]init];
mf.message= msg;
[self.messageFramesaddObject:mf];
//
[self.tableViewreloadData];
// 4.自动滚动表格到最后一行
NSIndexPath *lastPath = [NSIndexPathindexPathForRow:self.messageFrames.count- 1 inSection:0];
[self.tableViewscrollToRowAtIndexPath:lastPathatScrollPosition:UITableViewScrollPositionBottomanimated:YES];
}
/**
* 根据自己发的内容取得自动回复的内容
*
* @param text 自己发的内容
*/
- (NSString*)replayWithText:(NSString*)text
{
for (inti = 0; i<text.length; i++) {
NSString *word = [textsubstringWithRange:NSMakeRange(i,1)];
if (self.autoreply[word])return self.autoreply[word];
}
return @"滚蛋";
}
步骤八、其他的设置
//去除分割线
self.tableView.separatorStyle= UITableViewCellSeparatorStyleNone;
// 设置背景图片
self.tableView.backgroundColor= [UIColorcolorWithRed:224/255.0green:224/255.0blue:224/255.0alpha:1.0];
// 界面不允许被点击
self.tableView.allowsSelection= NO;
// 处理文本输入框
self.inputView.leftView= [[UITextFieldalloc]initWithFrame:CGRectMake(0,0,5,0)];
self.inputView.leftViewMode= UITextFieldViewModeAlways;
self.inputView.delegate= self;
self.tableView.separatorStyle= UITableViewCellSeparatorStyleNone;
// 设置背景图片
self.tableView.backgroundColor= [UIColorcolorWithRed:224/255.0green:224/255.0blue:224/255.0alpha:1.0];
// 界面不允许被点击
self.tableView.allowsSelection= NO;
// 处理文本输入框
self.inputView.leftView= [[UITextFieldalloc]initWithFrame:CGRectMake(0,0,5,0)];
self.inputView.leftViewMode= UITextFieldViewModeAlways;
self.inputView.delegate= self;
九、return键的处理
#pragma mark -文本框代理
/**
* 点击了return按钮(键盘最右下角的按钮)就会调用
*/
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
// 1.自己发一条消息
[selfaddMessage:textField.texttype:MJMessageTypeMe];
// 2.自动回复一条消息
NSString *reply = [selfreplayWithText:textField.text];
[selfaddMessage:replytype:MJMessageTypeOther];
// 3.清空文字
self.inputView.text= nil;
// 返回YES即可
return YES;
}
/**
* 点击了return按钮(键盘最右下角的按钮)就会调用
*/
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
// 1.自己发一条消息
[selfaddMessage:textField.texttype:MJMessageTypeMe];
// 2.自动回复一条消息
NSString *reply = [selfreplayWithText:textField.text];
[selfaddMessage:replytype:MJMessageTypeOther];
// 3.清空文字
self.inputView.text= nil;
// 返回YES即可
return YES;
}
qq聊天布局思路
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。