zoukankan      html  css  js  c++  java
  • swift 纯代码自定义cell(qq聊天界面)

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

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

    先放张效果图
    这里写图片描述

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

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

    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声明变量,并且初始化

    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内容和内部控件位置

    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,  50, height: 50)
    
            //3.设置正文
    
            //设置button显示
    
            textmsg?.setTitle(msg.text, forState: UIControlState.Normal)
            textmsg?.frame = CGRect(x: textX, y: 30,  size.width+30, height: size.height+30)
            textmsg?.titleLabel?.font = UIFont.boldSystemFontOfSize(14)
            textmsg?.titleLabel?.numberOfLines=0
            textmsg?.contentEdgeInsets = UIEdgeInsetsMake(15,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来做的、)

    关键代码:

     let size = NSString(string: msg.text).boundingRectWithSize(CGSizeMake(screenWdith!-140, CGFloat(MAXFLOAT)), options: NSStringDrawingOptions.UsesLineFragmentOrigin , attributes: [NSFontAttributeName:UIFont.boldSystemFontOfSize(14)], context: nil).size

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

    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)

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

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

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

     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

    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是做完了~·~

  • 相关阅读:
    flex + bison multiple parsers
    Educational Codeforces Round 95 (Rated for Div. 2)
    python学习笔记 day20 序列化模块(二)
    python学习笔记 day20 常用模块(六)
    python 学习笔记 常用模块(五)
    python学习笔记 day19 常用模块(四)
    python学习笔记 day19 常用模块(三)
    python学习笔记 day19 常用模块(二)
    python学习笔记 day19 作业讲解-使用正则表达式实现计算器
    python学习笔记 day19 常用模块
  • 原文地址:https://www.cnblogs.com/xingyun1992/p/7286567.html
Copyright © 2011-2022 走看看