最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

[已解决]swift中UITableView的Cell的高度UITableViewAutomaticDimension不完全工作

Swift crifan 6893浏览 0评论

用了自动布局后,列表的行的高度,返回的是UITableViewAutomaticDimension

    func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        print("MessageTableViewController heightForRowAtIndexPath indexPath = \(indexPath)")
       
        let message = self.messageList[indexPath.row]
       
        if message is ResourceMessage {
            return UITableViewAutomaticDimension
        }
       
//        if message is TextMessage {
            let calculatedcellHeight = MessageTableViewCell.calculateCellHeight(message)
           
            //        let cell = tableView.cellForRowAtIndexPath(indexPath) as! MessageTableViewCell
            //        let calculatedcellHeight = cell.calculateCellHeight()
           
            print("indexPath=\(indexPath), calculatedcellHeight=\(calculatedcellHeight)")
            return calculatedcellHeight
//        }
    }

结果是高度计算不准

效果是:

以及另外一个问题:

只有滚动之后,才能正常显示(虽然不是太准确的)高度:

搜:

UITableViewAutomaticDimension

uitableviewautomaticdimension not accurate

Ray Wenderlich | Tutorials for Developers and Gamers

ios – Setting rowHeight equal to UITableViewAutomaticDimension not working – Stack Overflow

调整自动布局后,结果还是不对:

代码是:

heightForRowAtIndexPath时返回的:

不论是:

UITableViewAutomaticDimension

还是,自己多加了点高度:

UITableViewAutomaticDimension + 40

都没用。

以及:

看了解释“Requests that UITableView use the default value for a given dimension.”后去:

主动把之前加上预估高度去掉:

let HeightMessageTableViewCellEstimatedRow:CGFloat = 60
//        self.messageTableView.estimatedRowHeight = HeightMessageTableViewCellEstimatedRow

都还是没用

搜:

uitableviewautomaticdimension not accurate

理解iOS 8中的Self Sizing Cells和Dynamic Type-CocoaChina_让移动开发更简单

Ray Wenderlich | Tutorials for Developers and Gamers

在viewDidLoad中加了:

        self.messageTableView.reloadSections(NSIndexSet(indexesInRange: NSMakeRange(0, self.messageTableView.numberOfSections)), withRowAnimation: UITableViewRowAnimation.None)

结果问题依旧。

ios – iOS8: Possible to use "tableview.rowHeight = UITableViewAutomaticDimension" for static cells? – Stack Overflow

最后的最后,解决办法是:

原先是少了bottom的约束:

                //file bubble view
                self.fileBubbleView = FileBubbleView(frame: CGRectZero, resourceMessage: resMessage)
                self.contentView.addSubview(self.fileBubbleView!)
                constrain(fileBubbleView!, avatarButton, userNameLabel) {fileBubbleView, avatarButton, userNameLabel in
                    if self.message.isDisplaySenderName {
                        fileBubbleView.top == userNameLabel.bottom
                    }else{
                        fileBubbleView.top == avatarButton.top
                    }
                                        
                    if self.message.directionType == MessageDirectionType.Receive {
                        fileBubbleView.left == avatarButton.right
                        fileBubbleView.right <= fileBubbleView.superview!.right WidthAvatarPadding SizeAvatarImage
                    }else if self.message.directionType == MessageDirectionType.Send {
                        fileBubbleView.right == avatarButton.left
                        fileBubbleView.left >= fileBubbleView.superview!.left + WidthAvatarPadding + SizeAvatarImage
                    }
                   
//                    fileBubbleView.height == 60
                    fileBubbleView.height == 54
                    fileBubbleView.width <= fileBubbleView.superview!.width 2 * (WidthAvatarPadding + SizeAvatarImage)
                }
            }

加上(之前缺少的)bottom的约束条件,就可以了

                //file bubble view
                self.fileBubbleView = FileBubbleView(frame: CGRectZero, resourceMessage: resMessage)
                self.contentView.addSubview(self.fileBubbleView!)
                constrain(fileBubbleView!, avatarButton, userNameLabel) {fileBubbleView, avatarButton, userNameLabel in
                    if self.message.isDisplaySenderName {
                        fileBubbleView.top == userNameLabel.bottom
                    }else{
                        fileBubbleView.top == avatarButton.top
                    }
                   
                    fileBubbleView.bottom <= fileBubbleView.superview!.bottom
                   
                    if self.message.directionType == MessageDirectionType.Receive {
                        fileBubbleView.left == avatarButton.right
                        fileBubbleView.right <= fileBubbleView.superview!.right WidthAvatarPadding SizeAvatarImage
                    }else if self.message.directionType == MessageDirectionType.Send {
                        fileBubbleView.right == avatarButton.left
                        fileBubbleView.left >= fileBubbleView.superview!.left + WidthAvatarPadding + SizeAvatarImage
                    }
                   
//                    fileBubbleView.height == 60
                    fileBubbleView.height == 54
                    fileBubbleView.width <= fileBubbleView.superview!.width 2 * (WidthAvatarPadding + SizeAvatarImage)
                }
            }

即可正常显示文件了:

[总结]

此处,如果想要避免

UITableViewAutomaticDimension

无法正确计算列表的行高,则需要:

确保你的View视图的约束constrain的

top

bottom

left(估计等价于Leading)

right(估计等价于Trailing)

都设置值了,就可以保证:

UITableViewAutomaticDimension

去帮你自动计算大小了。

注意:

对于每个使用了(添加了约束的)自动布局,借用UITableViewAutomaticDimension去自动计算行高的话,内部还是需要耗时的,尤其是行数很多(1000量级的)的时候,需要耗费很多时间

-》列表加载就显示很慢了

-》为了提高列表加载速度

-》可以去实现:估计的高度

即:

设置tableView.estimatedRowHeight

或:

实现:

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat

返回一个估计的高度

-》自己大概给个值,是自己的所有的列表的行的大致平均高度的值,即可。

-》比如我此处设置了60

        //improve perfomance
        self.messageTableView.estimatedRowHeight = HeightMessageTableViewCellEstimatedRow
    //above has set estimatedRowHeight, so not need estimatedHeightForRowAtIndexPath here
//    func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
//        //return UITableViewAutomaticDimension
//        return HeightMessageTableViewCellEstimatedRow
//    }

-》这样UITableView就可以快速加载单元格了

-》等到真的需要显示(单个页面的几行)的时候,再去真正调用heightForRowAtIndexPath去计算真正的高度

-》heightForRowAtIndexPath中的计算,可能会很耗时。

转载请注明:在路上 » [已解决]swift中UITableView的Cell的高度UITableViewAutomaticDimension不完全工作

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
84 queries in 0.180 seconds, using 22.22MB memory