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

  • 相关阅读:
    关于需求转化的事情
    自由邮件的配置
    广告数据关联CS后台数据
    向新同事学习,如何配置邮件
    渠道映射等关系
    机器学习基本概念
    家政业务系统常识
    SAP APO
    SAP Web Dynpro
    SAP Web Dynpro-监视应用程序
  • 原文地址:https://www.cnblogs.com/xingyun1992/p/7286567.html
Copyright © 2020-2023  润新知