用tableView可实现如QQ,飞信,微信等聊天软件的对话框效果。

要实现如图功能要解决以下几个问题:

1.对话框的高度能随着文本的多少动态变化,如果字数少于一行能存放的最大字数还要调整对话框的宽度,如果对话框的文字太少要保证对话框至少要与头像照片一样高

2.对话框是一个button,要完成对话框的背景的拉伸,使之与文字适合,点击对话框有高亮显示

3.要在toolbar中加入textfield与button,点击textfield键盘弹出后要动态调整toolbar高度使textfield不会被键盘遮挡

4.完成输入后键盘取消第一响应,textfield需要清空,tableView重新加载数据并滚动到最后一个cell

准备工作在storyboard中只需加入navigation controller并把viewController设置为rootViewController就完成工作,其他的部分全部用代码实现。包括tableView的生成cell的数据的载入全部用代码就可以实现。

为了展示效果先从字典中加载部分数据。

我定义了一个Message类来存放对话消息,定义字符串message存放内容,isMine来判断是我自己发的信息还是对方发的信息

Message.h

#import <Foundation/Foundation.h>@interface Message : NSObject
@property(nonatomic,strong)NSString *message;
@property(nonatomic,assign)BOOL isMine;
@end

头文件viewController.h

#import <UIKit/UIKit.h>
@interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>
@property(strong,nonatomic)UITableView *tableView;
@property(strong,nonatomic)NSMutableArray *dialogMessages;
@property(nonatomic,strong) UITextField *myTextField;
@property(nonatomic,strong) UIToolbar *myToolbar;
@property(nonatomic,strong) UIButton *myButton;
@end

里面定义了tableView,用来输入数据的myTextField,点击响应发送信息的myButton,和存放myTextField与myButton的myToolbar,最后是用来存储用于tableViewCell中的数据的数组dialogMessage。其中在头文件中一定不能忘记包含下面的委托,否则不能使用系统函数。

<UITableViewDataSource,UITableViewDelegate,UITextFieldDelegate>

读取字典中的数据

    const NSString *MsgKey = @"msg";const NSString *MineKey = @"ismine";NSString *path = [[NSBundle mainBundle] pathForResource:@"messages" ofType:@"plist"];NSArray *dataArray = [NSArray arrayWithContentsOfFile:path];[dataArray enumerateObjectsUsingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL *stop) {Message *message = [[Message alloc] init];message.message = dict[MsgKey];message.isMine = [dict[MineKey] boolValue];[self.dialogMessages addObject:message];}];//读取字典中的数据

代码生成界面各部分内容

tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, 320, 371)];tableView.delegate =self;tableView.dataSource =self;self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;myToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 372, 320, 44)];myTextField.delegate =self;myTextField = [[UITextField alloc] init];//初始化UITextFieldmyTextField.frame = CGRectMake(0, 0, 250, 32);myTextField.delegate = self;//设置代理myTextField.borderStyle = UITextBorderStyleRoundedRect;//设置textField的样式为圆角myTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;//垂直居中myTextField.placeholder = @"请输入内容";//内容为空时默认文字myTextField.returnKeyType = UIReturnKeyDone;//设置放回按钮的样式myTextField.keyboardType = UIKeyboardTypeDefault;//设置键盘样式为默认UIBarButtonItem *textfieldButtonItem =[[UIBarButtonItem alloc]initWithCustomView:myTextField];UIBarButtonItem *sendMessageButtonItem =[[UIBarButtonItem alloc]initWithTitle:@"发送" style:UIBarButtonItemStyleDone target:self action:@selector(sendMessage)];NSArray *textfieldArray=[[NSArray alloc]initWithObjects:textfieldButtonItem,sendMessageButtonItem,nil];[myToolbar setItems:textfieldArray];[self.view addSubview:tableView];[self.view addSubview:myToolbar];

切记要设置委托对象为self

tableView.delegate =self;
tableView.dataSource =self;
myTextField.delegate =self;

实现tableView

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{return 1;
}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{return [self.dialogMessages count];
}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{Message *msg = self.dialogMessages[indexPath.row];UIFont *font = [UIFont systemFontOfSize:12];CGSize size =[msg.message sizeWithFont:font constrainedToSize:CGSizeMake(115, 400) lineBreakMode: NSLineBreakByCharWrapping];if (size.height < 55) {//判断对话框的高度,如果比头像矮就设置为头像高度,否则就设置为对话框的文本高度加上间隔return 55;}else{return size.height+25+5;//与边线的间隔加上文本的上下缩进}
}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{float buttonHeight,buttonWidth;NSString *CellIdentifier=@"CellIdentifier";UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];if (cell == nil) {cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];}cell.selectionStyle = UITableViewCellSelectionStyleNone;//消去边线Message *msg = self.dialogMessages[indexPath.row];UIFont *font = [UIFont systemFontOfSize:12];//设置字体,这里使用了系统默认字体CGSize size =[msg.message sizeWithFont:font constrainedToSize:CGSizeMake(115, 400) lineBreakMode: NSLineBreakByCharWrapping];//计算文本高度if (size.height <16) {CGSize sizeSec=[msg.message sizeWithFont:font constrainedToSize:CGSizeMake(500, 15) lineBreakMode: NSLineBreakByCharWrapping];buttonWidth=sizeSec.width +35;//35是前缩进加上后缩进的宽度}else{buttonWidth = 150;}if (size.height <50) {//设置对话框高度buttonHeight = 50;//高度小于照片高度的就设置为照片高度}else{buttonHeight = size.height +25;}UIImage *normalImage,*highlightedImage;UIButton *dialogMessageButton =[[UIButton alloc]init];UIEdgeInsets insets;UIImage *headImage;UIImageView *headImageView =[[UIImageView alloc]init];if (msg.isMine ==true) {//判断信息来源,自己和别人的不一样的处理headImage =[UIImage imageNamed:@"me.jpg"];[headImageView setFrame:CGRectMake(5, 5, 50, 50)];normalImage = [UIImage imageNamed:@"mychat_normal"];highlightedImage = [UIImage imageNamed:@"mychat_focused"];insets = UIEdgeInsetsMake(10, 25, 15, 10);//设置文本的内边框,使文字与对话框更协调[dialogMessageButton setContentEdgeInsets:insets];//设置缩进[dialogMessageButton setFrame:CGRectMake(55, 5, buttonWidth, buttonHeight)];[dialogMessageButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];}else{headImage =[UIImage imageNamed:@"mate.jpg"];[headImageView setFrame:CGRectMake(265, 5, 50, 50)];normalImage = [UIImage imageNamed:@"matechat_normal"];highlightedImage = [UIImage imageNamed:@"matechat_focused"];insets = UIEdgeInsetsMake(10, 10, 15, 25);//设置文本的内边框[dialogMessageButton setFrame:CGRectMake(320-buttonWidth-55, 5,buttonWidth, buttonHeight)];[dialogMessageButton setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted];//设置点击时文字颜色变成蓝色}[headImageView setImage:headImage];NSMutableString *buttonName =[[NSMutableString alloc]initWithFormat:@"%@",msg.message];[dialogMessageButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];normalImage = [normalImage stretchableImageWithLeftCapWidth:normalImage.size.width*0.5 topCapHeight:normalImage.size.height*0.6];//设置图片拉伸区域highlightedImage = [highlightedImage stretchableImageWithLeftCapWidth:highlightedImage.size.width*0.5 topCapHeight:highlightedImage.size.height*0.6];//设置图片拉伸区域[dialogMessageButton setBackgroundImage:normalImage forState:UIControlStateNormal];//设置对话框图片[dialogMessageButton setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];//设置点击时对话框图片[dialogMessageButton setTitle:buttonName forState:UIControlStateNormal];[dialogMessageButton setContentEdgeInsets:insets];//设置缩进dialogMessageButton.titleLabel.font = font;dialogMessageButton.titleLabel.lineBreakMode = NSLineBreakByCharWrapping;dialogMessageButton.titleLabel.numberOfLines = 0;[cell.contentView addSubview:headImageView];[cell.contentView addSubview:dialogMessageButton];return cell;
}

其中

CGSize size =[msg.message sizeWithFont:font constrainedToSize:CGSizeMake(115, 400) lineBreakMode: NSLineBreakByCharWrapping];

的作用是计算在一定字体样式与大小(font)情况下文本(msg.message)在Width=115,Height=400的矩形约束下的文本所占高度,Height应设置的比较高足够容纳可能存放的文字数量才能保证结果不会偏差,NSLineBreakByCharWrapping是文本的换行方式我在上一篇博文中有介绍。150是我设置的button的最大宽度,减去了前后缩进的35就剩下115了。

button因为是矩形的所以它的实际大小是图片中黄色区域部分,所以要设置文字的缩进让文字不要在对话框外的区域(黄色区域),所以用到insets设置缩进。点击的时候点击到对话框外的区域也会实现高亮显示,所以可以将button的backgroundColor设为[UIColor clearColor]然后再设置对话框为imageVIew调整它们之间的位置实现更好的用户体验

 insets = UIEdgeInsetsMake(10, 10, 15, 25);//设置文本的内边框

这一句中UIEdgeInsetsMake(up,left,right,down)里面的参数分别为上,左,下,右逆时针的四个方向的缩进设置,然后通过[dialogMessageButton setContentEdgeInsets:insets]把数据传入button中

 if (size.height <16) {CGSize sizeSec=[msg.message sizeWithFont:font constrainedToSize:CGSizeMake(500, 15) lineBreakMode: NSLineBreakByCharWrapping];buttonWidth=sizeSec.width +35;//35是前缩进加上后缩进的宽度}else{buttonWidth = 150;}

上面一段代码中因为一行大小12的systemfont高度为15.00000...(float),浮点数不能直接用等于号判断是否满足要求,用等于号会出错,所以我用判断是否为小于16代替,当判断到文本高度为16时,我们故技重施,限制住高度为15,再用CGSize来得到文本的宽度,然后就把button宽度设置为文本宽度加上缩进,否则维持150不变

    [dialogMessageButton setBackgroundImage:normalImage forState:UIControlStateNormal];//设置对话框图片[dialogMessageButton setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];//设置点击时对话框图片

背景图片和titleColor都可以分别在UIControlStateNormal和UIControlStateHighLighted两种状态下设置,相当方便,读者也可自行尝试其他属性

tableView完成后就要着手完成textfield的功能了,在

    [self.view addSubview:tableView];[self.view addSubview:myToolbar];

后面加上

 //注册键盘出现与隐藏时候的通知[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(keyboadWillShow:)name:UIKeyboardWillShowNotificationobject:nil];[[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(keyboardWillHide:)name:UIKeyboardWillHideNotificationobject:nil];

然后是键盘出现与消失时调整toolbar位置函数

//键盘出现时候调用的事件
-(void) keyboadWillShow:(NSNotification *)note{NSDictionary *info = [note userInfo];CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;//键盘的frameCGFloat offY = (416-keyboardSize.height)-myToolbar.frame.size.height;//屏幕总高度-键盘高度-myToolbar高度[UIView beginAnimations:nil context:NULL];//此处添加动画,使之变化平滑一点[UIView setAnimationDuration:0.3];//设置动画时间 秒为单位myToolbar.frame =CGRectMake(0, offY, 320, 44);[UIView commitAnimations];//开始动画效果}
//键盘消失时候调用的事件
-(void)keyboardWillHide:(NSNotification *)note{[UIView beginAnimations:nil context:NULL];//此处添加动画,使之变化平滑一点[UIView setAnimationDuration:0.3];myToolbar.frame =CGRectMake(0, 372, 320, 44);[UIView commitAnimations];
}
//隐藏键盘方法
-(void)hideKeyboard{[myTextField resignFirstResponder];
}

textfield的委托事件

//开始编辑:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{return YES;
}//点击return按钮所做的动作:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{[textField resignFirstResponder];//取消第一响应return YES;
}//编辑完成:
- (void)textFieldDidEndEditing:(UITextField *)textField
{}-(void)viewDidDisappear:(BOOL)animated{[super viewDidDisappear:animated];[[NSNotificationCenter defaultCenter] removeObserver:self];//移除观察者
}

然后是button的响应函数

-(void)sendMessage{//完成输入响应函数 Message *newMessage =[[Message alloc]init];newMessage.message = [[NSString alloc]initWithString:myTextField.text];newMessage.isMine =YES;[self.dialogMessages addObject:newMessage];//把textField的文本加入到字典数组中[tableView reloadData];//tableView重新加载数据NSUInteger rowCount = [tableView numberOfRowsInSection:0];NSIndexPath* indexPath = [NSIndexPath indexPathForRow:rowCount-1 inSection:0];//indexPath设置成最后一个cell的下标[tableView scrollToRowAtIndexPath:indexPathatScrollPosition:UITableViewScrollPositionBottom animated:NO];//设置滚动到底部[myTextField resignFirstResponder];//键盘消失,取消第一响应myTextField.text =@"";//清空textField}

最后是设置cell的点击事件,让用户点击空白处键盘会消失

-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{[myTextField resignFirstResponder];
}

tableView实现对话框代码下载

用TableView实现聊天对话框相关推荐

  1. css聊天气派,css如何实现小尖角聊天对话框带尖角的说话泡泡效果

    css如何实现小尖角聊天对话框带尖角的说话泡泡效果 发布时间:2021-03-20 09:44:20 来源:亿速云 阅读:58 作者:小新 这篇文章主要介绍了css如何实现小尖角聊天对话框带尖角的说话 ...

  2. 轻松实现网页中通过链接跳转到QQ聊天界面,通过链接加QQ群,自动打开聊天对话框等等,包含电脑版和手机版的实现,示例部分Android和iOS的代码

    通过链接打开对话框: 打开qq聊天窗口的方法 <a href="http://wpa.qq.com/msgrd?v=3&uin=1450612626&site=qq&a ...

  3. HTML CSS JS实现网页聊天窗口,js实现聊天对话框

    本文实例为大家分享了js实现聊天对话框的具体代码,供大家参考,具体内容如下 .box{ width:300px; height:400px; border:1px solid blue; margin ...

  4. html做一个聊天输入框,js实现简易聊天对话框

    聊天对话框 *{font-size: 14px; padding:0; margin:0;} .main{ position: relative; margin: 20px auto; border: ...

  5. Vue实现简单聊天对话框案例

    功能:实现双人简单聊天对话框,见效果图 代码如下: <!DOCTYPE html> <html lang="en"><head><meta ...

  6. 互联网晚报 | 8月16日 | iPhone14或仍有刘海;​百度回应前腾讯新闻负责人王诗沐是否加入;微信聊天对话框支持放大编辑...

    iPhone14或仍有刘海,设计.芯片都不变 MacRumors总结了苹果发布会爆料信息.其中,iPhone14可能更像是"iPhone 13S",因为预计它不会有很多变化,将会带 ...

  7. C#实现微信聊天对话框

    前两天的<C#实现微信聊天对话框>大师给了不少的好的建议,本文基于进步并进行了改进,望大师一路来评论辩论~~~ 之前靠山的边框采取靠山图片的体式格式,今朝已采取GDI+直接绘制的体式格式, ...

  8. iPhone14或仍有刘海,设计、芯片都不变;微信聊天对话框支持放大编辑;Android 13正式版发布|极客头条...

    「极客头条」-- 技术人员的新闻圈! CSDN 的读者朋友们早上好哇,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧. 整理 | 梦依丹 出品 | CSDN(ID:CSDNnews ...

  9. 使用python自动发送消息到微信或者聊天对话框

    使用python自动发送消息到微信或者聊天对话框 环境准备 环境:python3.8 系统:win下 环境准备(默认win下已安装python3.8以上版本):以下环境准备只需要配置一次 1.wino ...

最新文章

  1. hdu5348 MZL's endless loop(欧拉回路)
  2. [INSHack2018]Tricky-Part1
  3. jQuery可放大预览的图片滑块
  4. 不同路径 II-dp
  5. DCT(离散余弦变换(DiscreteCosineTransform))
  6. 中国电子学会scratch等级考试三级
  7. Leetcode每日一题:1025.divisor-game(除数博弈)
  8. ffmpeg系列-编译
  9. c语言c99标准,C语言 1999年标准 (C99)
  10. vscode下报错:No such file or directory fatal error:no input files的一种比较坑爹的可能
  11. 升级版DC/DC转换器有什么优点?
  12. 上海二手房8月排名:链家、悟空找房、中原、太平洋、我爱我家、易居、房天下、iwjw、房多多、房好多、q房网、、、...
  13. linux键盘按键驱动
  14. 苏宁易购:前后端分离架构的落地思考
  15. 【b站雅思笔记】Charlie有好好学习 - 雅思机经8-14
  16. 软件测试就业前景怎样
  17. 对于makefile不支持c++11的处理
  18. java lambda表达式 list转string
  19. ES 问题 拼音 en ou等词被拆分,导致搜不到
  20. centos7防火墙端口设置

热门文章

  1. NFT 地板价计算方法
  2. 面试|应聘Java开发工程师的基本要求是什么?
  3. 股票查询系统,模糊查询,判断数值,字典,列表,字符串的运用python
  4. 【蓝桥杯单片机备赛】3.【SMG】共阳共阴数码管模板整理及真题实战心得
  5. 分享几种Spring Boot常用数据处理方式(含代码,粘贴可用)
  6. 基于区块链技术,电子商务平台将提高安全性和透明度
  7. 怎么给照片添加马赛克?这些方法值得收藏
  8. 怎么一键完美抠图?无需PS!快来看看!
  9. 2018 CodeM资格赛 下单
  10. Vue + Spring Boot 项目实战(二十二):生产环境初步搭建