聊天界面主要是cell的动态高度计算和效率的问题,参考网上的两篇文章:

1.优化UITableViewCell高度计算的那些事  http://www.cocoachina.com/ios/20150518/11854.html

2.动态计算UITableViewCell高度详解  http://www.cocoachina.com/industry/20140604/8668.html

因为对Autolayout也有一定的了解,决定一试,把动态调整高度交给ios自己处理。最后发现这个方案还是很好的。

一、在xib中布局,添加约束

1.添加四种view,同样需要先拖UILabel

@IBOutlet weak var bubbleImage: UIImageView!

@IBOutlet weak var time: UILabel!

@IBOutlet weak var icon: UIImageView!

@IBOutlet weak var content: UILabel!

2.设置view间的约束,要想让ios能自动调整高度,关键是高度方向的约束要连续完整,包括距离顶部,还有底部的距离。

a.从上到下,先设置time的约束:与顶部距离,高度

b.设置icon: 宽高 = 40,icon.top = time.bottom

c.设置bubbleImage: bubbleImage.top 与 icon.top对齐 ,与cell底部距离=4

d.设置content约束在bubbleImage内部:为了居中设置二者的centerX与centerY对齐,再设置content.leading >= bubble.leading+20,

content.top >= bubble.top+15 即可

注意点:

1.uilabel的preferredMaxLayoutWidth在xib和代码中设置都可以

2. uilabel会根据文字内容自动调整大小,但是好像只能放大。实测发现只有一个字母的时候,应该变小的,但是还是显示xib初始布局的大小。

而xib中启用autolayout就无法改变frame的初始宽高了。所以拖进去时最好将初始frame设小点。

cell配置代码:

class ChatTableViewCellA: UITableViewCell {

    @IBOutlet weak var bubbleImage: UIImageView!
@IBOutlet weak var time: UILabel!
@IBOutlet weak var icon: UIImageView!
@IBOutlet weak var content: UILabel!
var height:CGFloat! class func initChatCell(tableView:UITableView,message:TextMessage,iconname:String) -> ChatTableViewCellA?{ let Identifier = message.role == .Me ? "ChatTableViewCellAMe" : "ChatTableViewCellAOther"
var t:UITableViewCell? = tableView.dequeueReusableCellWithIdentifier(Identifier) if t == nil{
let index = message.role == .Me ? 1 : 0
t = NSBundle.mainBundle().loadNibNamed("ChatTableViewCellA", owner: nil, options: nil)[index] as? UITableViewCell
}
let cell:ChatTableViewCellA = t as! ChatTableViewCellA cell.time.text = message.time
cell.icon.image = UIImage(named: iconname) cell.content.text = message.text let bgImage = message.role == .Me ? UIImage(named:"chat_send_nor@2x")! : UIImage(named:"chat_recive_nor@2x")!
let H = floor(bgImage.size.height*0.5)
let W = floor(bgImage.size.width*0.5)
let insets = UIEdgeInsetsMake(H, W, bgImage.size.height-H-1, bgImage.size.width-W-1)
cell.bubbleImage.image = bgImage.resizableImageWithCapInsets(insets) cell.layoutIfNeeded()
cell.height = max(cell.bubbleImage.frame.maxY,cell.icon.frame.maxY) return t as? ChatTableViewCellA
} override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.backgroundColor = UIColor.whiteColor() self.time.textColor = UIColor.darkGrayColor()
self.time.font = UIFont.systemFontOfSize(13)
self.content.preferredMaxLayoutWidth = UIScreen.mainScreen().bounds.width - 120
self.content.numberOfLines = 0
self.content.lineBreakMode = .ByWordWrapping
} override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated) // Configure the view for the selected state
}
}

  关于cell的重用机制,为了提高效率,重用的cell应该只负责改变内容,其它固定不变的设置放在awakeFromNib中比较好。

在ViewController中实现代理方法和估算高度,根据cell的类型,估计的高度也可以比较准了:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
//debugPrint("Configure row:\(indexPath.row)")
// Configure the cell...
let msg = GlobalMsgCache.sharedInstance.getMessageAt(other.name!, index: indexPath.row) ?? BaseMessage()
if msg is TextMessage{
let message = msg as! TextMessage
let icon = (message.role == Role.Me ? self.me.icon:self.other.icon) ?? "defaulticon"
let cell:ChatTableViewCellA = ChatTableViewCellA.initChatCell(self.tableView, message: message,iconname: icon)!
return cell
}
else if msg is ProgressMessage{
let message = msg as! ProgressMessage
let icon = (message.role == Role.Me ? self.me.icon:self.other.icon) ?? "defaulticon"
let cell:ChatTableViewProgressCellA = ChatTableViewProgressCellA.initChatCell(self.tableView, message: message,iconname: icon)!
return cell
}
else{
let message = msg as! TipMessage
let cell:ChatTableViewTipCellA = ChatTableViewTipCellA.initChatCell(self.tableView, message: message)!
return cell
}
} func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
//debugPrint("row:\(indexPath.row),estimateheight\(cellHeightCache[indexPath.row] ?? 80)")
let msg = GlobalMsgCache.sharedInstance.getMessageAt(other.name!, index: indexPath.row) ?? BaseMessage()
if msg is TextMessage{
return 80
}
else if msg is ProgressMessage{
return 80
}
else{
return 50
}
}

  

聊天界面之气泡文本cell(二)使用Autolayout的更多相关文章

  1. 聊天界面之气泡文本cell(一)

    在实现qq聊天界面的过程中,使用UITableViewCell碰到了不少问题,这里还是记录一下以免遗忘. 气泡聊天cell的实现,网上最多的方法还是: 1.手动计算设置frame的值,文本的size使 ...

  2. C#+ html 实现类似QQ聊天界面的气泡效果

    /**定义两个人的头像*/ Myhead = "<img src=qrc:/chatdemo/Msg/Head.png width='30px'heigth='30px'>&qu ...

  3. 聊天界面之进度条cell(一)

    ProgressCell用于显示文件传输的进度,困难点在于根据下载进度更新cell的进度条,先后尝试了几种方法: 1.有新的下载进度时,直接调用reloadData() 2.使用reloadRowsA ...

  4. QQ聊天界面的布局和设计(IOS篇)-第一季

    我写的源文件整个工程会再第二季中发上来~,存在百度网盘, 感兴趣的童鞋, 可以关注我的博客更新,到时自己去下载~.喵~~~ QQChat Layout - 第一季 一.准备工作 1.将假数据messa ...

  5. Android学习笔记(十二)——实战:制作一个聊天界面

    //此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 运用简单的布局知识,我们可以来尝试制作一个聊天界面. 一.制作 Nine-Patch 图片 : Nine-Pa ...

  6. android 仿QQ气泡聊天界面

    1.现在的QQ,微信等一些APP的聊天界面都是气泡聊天界面,左边是接收到的消息,右边是发送的消息, 这个效果其实就是一个ListView在加载它的Item的时候,分别用了不同的布局xml文件. 2.效 ...

  7. Objective-c——UI基础开发第八天(QQ聊天界面)

    一.知识点: QQ聊天界面 双模型的使用(dataModel和frameModel) UITextField的使用 通知的使用 拉伸图片的两种方法(slicing/image对象的resizeable ...

  8. iOS开发——UI_swift篇&TableView自定义聊天界面

    TableView自定义聊天界面   1,下面是一个放微信聊天界面的消息展示列表,实现的功能有: (1)消息可以是文本消息也可以是图片消息 (2)消息背景为气泡状图片,同时消息气泡可根据内容自适应大小 ...

  9. Swift - 自定义单元格实现微信聊天界面

    1,下面是一个放微信聊天界面的消息展示列表,实现的功能有: (1)消息可以是文本消息也可以是图片消息 (2)消息背景为气泡状图片,同时消息气泡可根据内容自适应大小 (3)每条消息旁边有头像,在左边表示 ...

随机推荐

  1. Windows下mock环境搭建-加速项目Api开发

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 公司进行技术部拆分,以项目制作为新的开发模式,前端+移动端+后端,于是加速Api开发变得很有必要,准 ...

  2. Selenium脚本编写环境的搭建/XPath

    编写环境主要分为三个部分: JUnit : java单元测试框架: Firebug: firefox 附加组件,Firebug是firefox下的一个扩展,能够调试所有网站语言,如Html,Css等, ...

  3. iOS:给Git仓库上传代码时,超过100M会被拒绝(例如github和oschina)

    处理GitHub不允许上传大于100M文件问题?本人也遇到这个坑... 来自转载,原文链接:http://www.cnblogs.com/qmmq/p/4604862.html 1.报错: 自己的项目 ...

  4. pod install出现[!] /bin/bash -c错误,Installing Realm报错

    pod install出现错误,具体错误信息如下: Installing Realm () [!] /bin/bash -c set -e sh build.sh cocoapods-setup co ...

  5. 实例演示使用RDIFramework.NET 框架的工作流组件进行业务流程的定义—请假申请流程-Web

    实例演示使用RDIFramework.NET 框架的工作流组件 进行业务流程的定义—请假申请流程-Web 参考文章: RDIFramework.NET — 基于.NET的快速信息化系统开发框架 — 系 ...

  6. EF CodeFirst增删改查之‘CRUD’

    最近悟出来一个道理,在这儿分享给大家:学历代表你的过去,能力代表你的现在,学习代表你的将来. 十年河东十年河西,莫欺少年穷 学无止境,精益求精    本篇旨在学习EF增删改查四大操作 上一节讲述了EF ...

  7. java 静态函数锁对象说明

    在内存加载.class文件后,会自动创建一个对象,用于保存class的信息,与我们程序员手工创建的对象不一样.

  8. 函数nvl 和decode

    decode(nvl(kkc.category, 'one'),'one','普通','two','精品','three','行业','four','白金')

  9. Java关于md5+salt盐加密验证

    一.陈述一下工作流程: 1.根据已有的密码字符串去生成一个密码+盐字符串,可以将盐的加密字符串也存放在数据库(看需求), 2.验证时将提交的密码字符串进行同样的加密再从数据库中取得已有的盐进行组合密码 ...

  10. Linux基础命令介绍七:网络传输与安全 wget curl rsync iptables

    本篇接着介绍网络相关命令:wget 文件下载工具.curl 网络数据传输工具.rsync 文件传输工具等. 本篇接着介绍网络相关命令 1.wget 文件下载工具 wget [option]... [U ...