在 UITableViewCell 中获取自定义单元格的高度

Posted

技术标签:

【中文标题】在 UITableViewCell 中获取自定义单元格的高度【英文标题】:getting the height of the custom cell in UITableViewCell 【发布时间】:2018-11-16 02:56:14 【问题描述】:

我正在创建一个类似气泡聊天的应用程序。我为接收和发送气泡聊天创建了自定义函数。

创建它们后,我已将它们添加到使用 UITableView 创建的单元格中。

但是,我无法设置单元格的高度,具体取决于自定义单元格本身的高度。

例如,某些传入的文本可能比之前的要长。

因此我似乎无法根据自定义气泡聊天高度设置每个单元格。

请帮忙!

这是我的表格视图函数

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return arrMsg.count


// second
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 

    return 100


// lastly created
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for:indexPath)

    if arrMsg[indexPath.row]["type"] as! String == "outgoing" 
        cell.contentView.addSubview(createOutGoingBubble(msg: arrMsg[indexPath.row]["message"] as! String))
    
    if arrMsg[indexPath.row]["type"] as! String == "incoming" 
        cell.contentView.addSubview(createIncomingBubble(mymsg: arrMsg[indexPath.row]["message"] as! String))
    
    return cell

This is how it looks currently

如何根据 heightforrowat 函数内部创建的自定义气泡设置单元格的高度?

大概是用线求高并返回:

arrMsg[indexPath.row]["message"] as! String == "outgoing" 

**这是我创建要添加到 tableviewcell 中的自定义气泡聊天的功能

func createOutGoingBubble(msg:String) -> UIView 

    let subV = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))

    let label = UILabel()
    label.numberOfLines = 0
    label.font = UIFont.systemFont(ofSize: 18)
    label.textColor = .white
    label.text = msg

    let constraintRect = CGSize(width: 0.66 * view.frame.width,
                                height: .greatestFiniteMagnitude)
    let boundingBox = msg.boundingRect(with: constraintRect,
                                       options: .usesLineFragmentOrigin,
                                       attributes: [.font: label.font],
                                       context: nil)
    label.frame.size = CGSize(width: ceil(boundingBox.width),
                              height: ceil(boundingBox.height))

    let bubbleSize = CGSize(width: label.frame.width + 28,
                            height: label.frame.height + 20)

    let outgoingMessageView = UIImageView(frame:
        CGRect(x: view.frame.width - bubbleSize.width - 20,
               y: bubbleSize.height - 25,
               width: bubbleSize.width,
               height: bubbleSize.height))

    let bubbleImage = UIImage(named: "outgoing")?
        .resizableImage(withCapInsets: UIEdgeInsets(top: 17, left: 21, bottom: 17, right: 21),
                        resizingMode: .stretch)
        .withRenderingMode(UIImage.RenderingMode.alwaysTemplate)

    outgoingMessageView.image = bubbleImage
    outgoingMessageView.tintColor = UIColor(red: 0.40 , green: 0.71, blue: 1.00, alpha: 1)

    subV.addSubview(outgoingMessageView)

    label.center = outgoingMessageView.center

    subV.addSubview(label)

    return subV

提前致谢!

【问题讨论】:

你能把代码带入问题吗?提前致谢。 编辑完成!我的模拟器的图像也在那里。 @benc 提示:您应该在 cellForRowAt 方法中添加视图!您应该创建一个自定义单元格类并在其中放置气泡,然后仅在 cellForRowAt 中添加文本。此外,如果您设置了气泡相对于单元格的contentView 的约束,则自动尺寸应该注意高度。 感谢@RakeshaShastri,但我试图只使用一个 ViewController 并填充其中的所有内容。 @IskandarSalleh 除非您在UITableViewCell 中使用默认标签和图像视图,否则您应该每次都创建一个自定义表格视图单元格。 “我试图只使用一个 ViewController 并填充其中的所有内容。” 为什么?我也不是要你创建一个新的视图控制器。只是一个自定义UITableViewCell。您应该查找一些有关表视图的教程。您似乎不熟悉如何使用它们。 【参考方案1】:

您可以使用 Autolayout 来实现相同的功能,并从所有编码部分中解放出来。只需设置与单元格关联的内部视图的约束,然后对以下代码进行右移即可。

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
return UITableViewAutomaticDimension

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        let cell:ChatSenderTableViewCell = (tableView.dequeueReusableCell(withIdentifier: "ChatSenderTableViewCell", for: indexPath) as? ChatSenderTableViewCell)!

        cell.LabelChatMessage.text = "Your Message"
        cell.LabelChatMessage.numberOfLines = 0
        cell.LabelChatMessage.sizeToFit()

        return cell


我正在使用自定义单元格名称 ChatSenderTableViewCell 来创建气泡状效果,其中包含用于发送或接收消息的标签。

【讨论】:

【参考方案2】:

在视图内部使用标签,并根据您的需要使用顶部和底部的边距。此外,您需要在 UIlabel 中设置 0 行数。你可以使用 label.numberoflines = 0 来做到这一点。 此外,您需要添加以下代码以根据其中的文本更改行的高度。

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    return UITableViewAutomaticDimension

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat 
    return UITableViewAutomaticDimension

【讨论】:

【参考方案3】:

你可以试试这个:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 

    guard let cell = tableView.cellForRow(at: indexPath) else  return 0 
    return cell.intrinsicContentSize.height

intrinsicContentSize 是接收视图的自然大小,仅考虑视图本身的属性。

【讨论】:

以上是关于在 UITableViewCell 中获取自定义单元格的高度的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 cellForRowAtIndexPath 从 TableView 中获取自定义 UITableViewCell?

在 Swift 中访问自定义 UITableViewCell UILabel 文本会引发错误

如何从自定义 UITableViewCell 获取值到 ViewController?

Objective-C:在不可见的自定义 UITableViewCell 上获取属性的值

Swift - 如何从单元格内单击 UIImageView 上的自定义 UITableViewCell 获取行数据

在自定义 UITableViewCell 中按下 UIButton 时如何获取 indexPathForSelectedRow