我在容器视图中使用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()
}
现在我正在从容器视图控制器和chnanging height
重新加载答案 0 :(得分:8)
我尝试了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
}
}
}
答案 1 :(得分:2)
您的大多数方法都是正确的,也可以在下面添加以下步骤。如果你已经做了任何一个标记的步骤。
答案 2 :(得分:1)
虽然此处提供的答案是正确的,但这是Apple Developer Forum的另一种解释,该解释指出contentSize最初与estimated
值相同。所以将其设为零对我有用。
tableView.estimatedRowHeight = 0
这是苹果开发者论坛的答案:
在iOS 11中,表格视图默认使用估计的高度。这意味着contentSize最初与估计值相同。如果您需要使用contentSize,则需要通过将3个估计的高度属性设置为零来禁用估计的高度:tableView.estimatedRowHeight = 0 tableView.estimatedSectionHeaderHeight = 0 tableView.estimatedSectionFooterHeight = 0
答案 3 :(得分:0)
如果您使用的是iOS 13和/或Combine(例如我),则可以通过表格视图的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
闭包中放置断点,则可以在设备上实时查看。