在具有动态高度的 IB uitableviewcell 中使用带有 XIB 的自定义视图

Posted

技术标签:

【中文标题】在具有动态高度的 IB uitableviewcell 中使用带有 XIB 的自定义视图【英文标题】:Use custom view with XIB in IB uitableviewcell w/dynamic height 【发布时间】:2016-11-22 14:23:16 【问题描述】:

我有一个单元格,该单元格的内容可能与其他单元格不同,(而其他单元格属性相同) - 我认为由 nib 支持的自定义视图在这种情况下会很好用,但我遇到了在高度是动态的单元格中使用自定义视图时出现问题。

故事板:

这是一个带有 UITableView 和自定义 UITableViewCell、MessageTableViewCell 的 UIViewController,实现如下:

class MessageTableViewCell: UITableViewCell 

@IBOutlet weak var avatar: UIImageView!
@IBOutlet weak var initials: UILabel!
@IBOutlet weak var timestamp: UILabel!
@IBOutlet weak var messageView: UIView!

override func awakeFromNib() 
    super.awakeFromNib()
    // Initialization code


override func setSelected(_ selected: Bool, animated: Bool) 
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state



在视图控制器的 cellForRowAtIndexPath 方法中,我尝试使用来自 messageView 的框架(视图控制器单元格中的白框)来实例化由 xib 支持的 UIView。

自定义视图:

它的实现:

类 MessageView: NibLoadingView

@IBOutlet weak var message: UILabel!


NibLoadingView 实现: (信用:https://***.com/a/40051928/4096655)

class NibLoadingView: UIView 

weak var view: UIView!

override init(frame: CGRect) 
    super.init(frame: frame)
    nibSetup()


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)
    nibSetup()


private func nibSetup() 
    backgroundColor = .clear

    view = loadViewFromNib()
    view.frame = bounds
    view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    view.translatesAutoresizingMaskIntoConstraints = true

    addSubview(view)


private func loadViewFromNib() -> UIView 
    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
    let nibView = nib.instantiate(withOwner: self, options: nil).first as! UIView

    return nibView


行实现的单元格:

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

    guard let cell = tableView.dequeueReusableCell(withIdentifier: "messageCell") as? MessageTableViewCell else 
        return UITableViewCell()
    

    let frame = cell.messageView.frame
    let messageView = MessageView(frame: frame)
    messageView.message.text = messages[indexPath.row]
    cell.addSubview(messageView)

    return cell

结果:

简短的故事是我想在我通常认为的不同单元格之间分享一些共同属性,并尝试为彼此不同的单元格部分创建自定义视图,其中一些具有动态高度.谢谢阅读。

【问题讨论】:

再想一想,当我添加这些行时它对我有用:view.frame = bounds view.autoresizingMask = [.flexibleWidth, .flexibleHeight] view.translatesAutoresizingMaskIntoConstraints = true 但请参阅下面的评论用于 UITableViewCell 中的安全区域约束与 contentView 约束 【参考方案1】:

您不需要创建自定义视图 MessageView,而是需要在 messageView 中添加 MessageView 的内容,这是您在 viewController 上的原型单元格 MessageTableViewCell 中添加的视图,并且不要忘记出口,并在 messageView 约束中给出标签前导、顶部、尾随和底部, 最后在你的 viewController 中而不是调用 tableView(_:heightForRowAt:) 调用 tableView(_:estimatedHeightForRowAt:) UITableViewDelegate 方法。

【讨论】:

重点是MessageView应该可以和其他view互换。否则我会在 IB 中为我需要的每种不同类型的单元做这一切。 @thefredelement 好的,然后将正确的约束添加到MessageView 内的标签中,然后调用tableView(_:estimatedHeightForRowAt:) 以便单元格高度动态增加。 @FredFaust 您找到解决方案了吗?我遇到了同样的问题。我发现的一件事是,如果在具有动态高度的常规 uitableviewcell 中,如果将最顶部和最底部项目的顶部和底部约束连接到安全区域,则动态高度不起作用。如果将它们连接到 contentView 动态高度就可以了。我认为这与那个错误有关,但我不能确定。 @C0D3 你找到解决方案了吗?

以上是关于在具有动态高度的 IB uitableviewcell 中使用带有 XIB 的自定义视图的主要内容,如果未能解决你的问题,请参考以下文章

NSLayoutConstraint 和动态 UITableViewCell 高度

无论文本如何,UILabel 都会将高度调整为 0

无法与 IB 中的约束建立出口连接

如何在 iOS 中创建具有动态 tableview 高度的动态 tableview 单元格

在具有动态高度的视图末尾添加一个 UIButton

具有动态内容、动态布局和动态高度的 UITableViewCell