【问题标题】:uitableview content size is not returning correctly swiftuitableview 内容大小未正确返回 swift
【发布时间】:2017-03-09 10:38:11
【问题描述】:

我在容器视图中使用 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()
}

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

【问题讨论】:

  • 请同时添加相关代码和约束。
  • @agent_stack 请检查我更新的问题
  • 您的标签内容正在发生变化,对于该内容,您必须更改单元格高度。我说的对吗??

标签: ios uitableview autolayout contentsize


【解决方案1】:

我尝试了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
        }
    }
} 

【讨论】:

  • 赞美上帝免税。
  • 在我尝试了一切之后,这是唯一有效的解决方案。在 iOS 13 中有一个错误,其中“tableView.contentSize.height”只是返回错误。观察答案中显示的属性,确实提供了它的真正价值。
  • 不行! ? 这是我能为 iOS 13 找到的唯一解决方案!谢谢一百万!
  • 经过漫长的一天搜索这个问题后,我现在可以睡觉了。这个解决方案就像一个魅力。
  • 非常适合(iOS 13,*)的答案。谢谢。
【解决方案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
    }
    

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

预期输出:

【讨论】:

  • 我没有添加 uilabel heght,除非我做了所有步骤,
【解决方案3】:

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

tableView.estimatedRowHeight = 0

这是来自苹果开发者论坛的答案:

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

【讨论】:

    【解决方案4】:

    如果您使用的是 iOS 13 和/或 Combine(就像我一样),那么您可以使用 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 闭包中放置断点,您可以在设备上实时看到这些值。

    【讨论】:

      猜你喜欢
      • 2012-10-22
      • 1970-01-01
      • 1970-01-01
      • 2021-03-15
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多