swift 纯代码自定义cell(qq聊天界面)

前端之家收集整理的这篇文章主要介绍了swift 纯代码自定义cell(qq聊天界面)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

本人也是初学者,如有错误,请指正~

网上大多数都是oc语言的例子,swift的比较少,我就写一篇抛砖引玉

先放张效果

感觉做起来比Android麻烦百倍,文本高度要自己计算,cell行高也要自己计算。(Android里面一个wrap_content就都解决了)
为什么不用xib自定义呢,我表示那个情况下更加复杂,高度更不知道如何计算、还有图片拉伸的问题、

开始正文:
1.导入图片,plist文件,字典转模型

@H_301_16@import UIKit class Msg: NSObject { var text :String! var time :String! var type :NSNumber! override init() { super.init() } init(dir : Dictionary<String,AnyObject>) { super.init() setValuesForKeysWithDictionary(dir) } func getMsgArray() -> Array<Msg> { var array : Array<Msg> = [] //取到plist文件路径 let diaryList:String = NSBundle.mainBundle().pathForResource("messages",ofType:"plist")! //取出plist文件数据 let arraylist = NSMutableArray(contentsOfFile: diaryList)! for i in arraylist { let msg = Msg(dir: i as! Dictionary<String,AnyObject> ) array.append(msg) } return array } }

这里也弄了很久,oc里面是没有Array,只有NSArray,两者区别大的很,Array很像Java里面的ArrayList,需要加泛型,并且是一个结构体。关键方法setValuesForKeysWithDictionary、模型类的变量类型和名字都必须和plist文件一致!

2.创建自定义cell 继承UITableViewCell
下面按照纯代码自定义cell的方式一步步创建
2.1声明变量,并且初始化

@H_301_16@import UIKit class MsgCodeCell: UITableViewCell { var textmsg :UIButton? var icon :UIImageView? var time :UILabel? var screenWdith : CGFloat? override func awakeFromNib() { super.awakeFromNib() // Initialization code //xib自定义cell } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } override init(style: UITableViewCellStyle,reuseIdentifier: String?) { super.init(style: style,reuseIdentifier: reuseIdentifier) //代码自定义cell的入口方法~ textmsg = UIButton(); icon = UIImageView(); time = UILabel(); //这里做一些基本属性设置 time?.bounds = CGRect(x: 0,y: 0,width: 80,height: 10) time?.font = UIFont.boldSystemFontOfSize(12) screenWdith = UIScreen.mainScreen().bounds.size.width //先不设置frame和content contentView.addSubview(textmsg!) contentView.addSubview(icon!) contentView.addSubview(time!) }

初始化后,进行一些基本属性的设置,如字体,一些已经可以确定的位置大小,具体的位置需要等到外部数据赋值进来才能确定。

3.提供外部方法设置cell内容和内部控件位置

@H_301_16@func setMsgModle(msg:Msg) { //1.设置时间 time?.text = msg.time time?.center = CGPoint(x: contentView.center.x,y: 10) //2.设置头像 var textX : CGFloat = 0 var iconX : CGFloat = 0 var backimage : UIImage! //计算文字宽高! let size = NSString(string: msg.text).boundingRectWithSize(CGSizeMake(screenWdith!-140,CGFloat(MAXFLOAT)),options: NSStringDrawingOptions.UsesLineFragmentOrigin,attributes: [NSFontAttributeName:UIFont.boldSystemFontOfSize(14)],context: nil).size if msg.type == 0 { //发送者 iconX = screenWdith! - 60 icon?.image = UIImage(named: "me") textX = screenWdith! - size.width-100 backimage = UIImage(named: "chat_send_nor") }else{ //接收者 iconX = 10 icon?.image = UIImage(named: "other") backimage = UIImage(named: "chat_recive_press_pic") textX = 70 } icon?.frame = CGRect(x: iconX,y: 30,width: 50,height: 50) //3.设置正文 //设置button显示 textmsg?.setTitle(msg.text,forState: UIControlState.Normal) textmsg?.frame = CGRect(x: textX,width: size.width+30,height: size.height+30) textmsg?.titleLabel?.font = UIFont.boldSystemFontOfSize(14) textmsg?.titleLabel?.numberOfLines=0 textmsg?.contentEdgeInsets = UIEdgeInsetsMake(15,15,15); let inset = UIEdgeInsets(top: (backimage?.size.height)!*0.5,left: (backimage?.size.width)!*0.5,bottom: (backimage?.size.height)!*0.5,right: (backimage?.size.width)!*0.5) let newimage = backimage?.resizableImageWithCapInsets(inset) textmsg?.setBackgroundImage(newimage,forState: UIControlState.Normal) }

这里关键是文字宽高的计算,和文字背景图片拉伸计算、(这里最好不要用label来显示正文,因为label要设置背景图片的话,会比较麻烦,所以这边是用button来做的、)

关键代码

@H_301_16@let size = NSString(string: msg.text).boundingRectWithSize(CGSizeMake(screenWdith!-140,context: nil).size

首先,String对象是没有这个方法,先转成NSString,调用boundingRectWithSize,第一个参数是文字所能接受的最大宽高,类型是CGSize,这边的意思是宽度最大是 屏幕宽度-140 (为何减去140? 这里头像算50 ,然后间隙 都是 10 ,两边头像加间隙 10+50+10 +10+50+10),高度最大表示换行、第二个参数是绘制属性(不清楚),第三个是字体属性,这里可以传字体大小,字体类型等等

@H_301_16@let inset = UIEdgeInsets(top: (backimage?.size.height)!*0.5,right: (backimage?.size.width)!*0.5) let newimage = backimage?.resizableImageWithCapInsets(inset)

这里做图片拉伸,表示的是只有中间拉伸,四周不变~(和.9图片一个意思)

好的,这里自定义cell基本完了

3.计算行高
文字高度和头像高度中的最大值
在tableview中写代理方法

@H_301_16@override func tableView(tableView: UITableView,heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { var rowheight :CGFloat = 0 let msg = array[indexPath.row] //计算文字宽高! let size = NSString(string: msg.text).boundingRectWithSize(CGSizeMake(screenWdith!-140,CGFloat(MAXFLOAT)),options: NSStringDrawingOptions.UsesLineFragmentOrigin,attributes: [NSFontAttributeName:UIFont.boldSystemFontOfSize(14)],context: nil).size //4.计算总高! if size.height > 20{ // 字的高度 rowheight = size.height+70 }else{ //图片的高度 rowheight = 90 } return rowheight }

4.重用cell

@H_301_16@override func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { //这里做自定义cell重用 var cell = tableView.dequeueReusableCellWithIdentifier("cell") if cell == nil { cell = MsgCodeCell(style: UITableViewCellStyle.Default,reuseIdentifier: "cell") cell!.selectionStyle = UITableViewCellSelectionStyle.None NSLog("初始化cell") } (cell as! MsgCodeCell).setMsgModle(array[indexPath.row]) return cell! }

至此,cell是做完了~·~

猜你在找的Swift相关文章