8

我在容器视图中使用 uitableview,所以想根据内容大小高度设置我的容器高度。因此,在重新加载 tableview 后,我正在更改容器的高度。但它似乎是根据估计的高度计算的。它没有给出实际高度。

这是我的约束布局。

谢谢..在此处输入图像描述

    instructiontableview.estimatedRowHeight = 55

    instructiontableview.rowHeight = UITableViewAutomaticDimension

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

  }

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

    // assigning multiline text to my label 


        cell.layoutIfNeeded()
        cell.sizeToFit()
        return cell
    }
    return UITableViewCell()
}

现在我正在从我的容器视图控制器重新加载并更改高度

4

4 回答 4

34

我尝试reloadData()layoutIfNeeded()尝试了许多不同的方法。没有什么对我有用。最后我通过使用解决了它KVO

这是我的代码

override  func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.instructiontableview.addObserver(self, forKeyPath: "contentSize", options: .new, context: nil)

}
override func viewWillDisappear(_ animated: Bool) {
    self.instructiontableview.removeObserver(self, forKeyPath: "contentSize")
    super.viewWillDisappear(true)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?){
    if(keyPath == "contentSize"){

        if let newvalue = change?[.newKey]{
            let newsize  = newvalue as! CGSize
            self.heightofinstructioncontainerview.constant = newsize.height
        }
    }
} 
于 2017-03-14T07:10:36.783 回答
2

您的大多数方法都是正确的,请在下面添加此步骤。如果您已经完成任何步骤,请将其标记为复选标记。

  1. 将标签numberOfLines属性更改为零

在此处输入图像描述

  1. 为标签添加约束

在此处输入图像描述

  1. 改变高度约束关系

在此处输入图像描述

  1. 实现这两个 tableView 委托方法

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

现在运行您的项目并检查。

预期输出:

在此处输入图像描述

于 2017-03-09T11:22:10.623 回答
2

虽然此处提供的答案是正确的,但这是Apple Developer Forum的另一种解释,其中指出 contentSize 与estimated最初的值一样。所以把它归零对我有用。

tableView.estimatedRowHeight = 0

以下是苹果开发者论坛的答案:

在 iOS 11 中,表格视图默认使用估计高度。这意味着 contentSize 与最初的估计值一样。如果您需要使用 contentSize,您需要通过将 3 个估计高度属性设置为零来禁用估计高度:tableView.estimatedRowHeight = 0 tableView.estimatedSectionHeaderHeight = 0 tableView.estimatedSectionFooterHeight = 0

于 2020-04-14T08:19:25.173 回答
1

如果您使用的是 iOS 13 和/或组合(就像我一样),那么您可以使用 tableview 的 KVO 属性中的发布者

tableView.publisher(for: \.contentSize)
       .receive(on: RunLoop.main)
       .sink { size in
           self.myViewsHeightConstraint.constant = size.height
           self.tableView.isScrollEnabled = size.height > self.tableView.frame.height
       }
       .store(in: &cancellables)

sink这对我来说非常有用,并且在每次布局传递时都会发布新值,如果您在闭包中放置断点,您可以在设备上实时看到这些值。

于 2019-09-21T16:12:03.400 回答