zoukankan      html  css  js  c++  java
  • 聊天界面之气泡文本cell(二)使用Autolayout

    聊天界面主要是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
            }
        }
    

      

  • 相关阅读:
    年末deadline汇总
    [线性代数]2016.12.19周一作业
    [线性代数]2016.12.15周四作业
    Android SDK的安装与环境变量的配置
    安装JDK环境变量的配置
    Python中单引号,双引号,三引号
    带有支付功能的产品如何进行测试
    Android稳定性测试工具Monkey的使用
    mysql数据库单表增删改查命令
    svn
  • 原文地址:https://www.cnblogs.com/mlj318/p/5836457.html
Copyright © 2011-2022 走看看