【问题标题】:Swift / how to use UITextView with dynamic height INSIDE UITableViewCell with dynamic heightSwift / 如何使用具有动态高度的 UITextView INSIDE UITableViewCell 与动态高度
【发布时间】:2016-09-14 07:38:25
【问题描述】:

我正在使用以下代码使 UITableViewCell 具有动态高度:

tableView.estimatedRowHeight = 155
tableView.rowHeight = UITableViewAutomaticDimension

这段代码让 UITextView 根据内容改变它的高度。

extension NewUserTweetTableVC: UITextViewDelegate {

    func textViewDidChange(textView: UITextView) {
        let fixedWidth = textView.frame.size.width
        textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
        let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
        var newFrame = textView.frame
        newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
        textView.frame = newFrame    
    }
}

一旦我在运行时更改 UITextView 的文本,UITextView 的高度就会发生变化,但 UITableViewCell 的高度不会。我该如何改变呢?非常感谢您的帮助。

【问题讨论】:

标签: ios swift uitableview


【解决方案1】:

以编程方式获取文本视图的高度...

let textView = UITextView()//your Text view
let sizeThatShouldFitTheContent = textView.sizeThatFits(textView.frame.size)
let height = sizeThatShouldFitTheContent.height

或者试试这个演示...

在 UITableView 中自定义 UITextView 的大小

https://www.damienpontifex.com/posts/self-sizing-uitableviewcell-with-uitextview-in-ios8/

【讨论】:

  • 即使 stackoverflow 不希望人们只是发布链接,因为链接可能会关闭,这实际上帮助了我。
  • 现在链接失效了:(
  • 上述链接失效
  • 此链接已重新上线,但我认为值得在这里总结其内容,因为它确实运行良好。此处列出的大多数其他答案只是拼图中的一部分。简而言之,禁用文本视图的滚动,确保您可以在文本视图上初始化您的值,以便它会调用 textViewDidChange,然后计算高度是否已更改,如果是,则在 tableView 上调用 begin/endUpdates,同时包装/将这些调用夹在 UIView.setAnimationsEnabled(false/true)
  • 这真的很有帮助...谢谢@rahul 和 rs7。
【解决方案2】:

如果您使用UITableViewAutomaticDimension,那么您必须从上到下设置串行约束。没有自动布局或适当的约束UITableViewAutomaticDimension 将无法工作。所以你可以像这样管理这个东西:set top,bottom,leading,trailing and fixed height 约束到你的textview。然后取出fixed height constraint 的出口并增加它的constant,而不是更改或设置textview 的框架,我认为一切都会起作用!

【讨论】:

  • 需要禁用文本视图的滚动
  • 设置顶部、底部、前导、尾随、禁用滚动。一切正常
【解决方案3】:

第 1 步,禁用 TextView 的滚动
第 2 步,添加上、左、右和下约束
第三步,将 Delegate 设置为 textView
第四步,在下面实现 UITextViewDelegate 方法

- (void)textViewDidChange:(UITextView *)textView {
[UIView setAnimationsEnabled:false];
[textView sizeToFit];
[self.tableView beginUpdates];
[self.tableView endUpdates];
[UIView setAnimationsEnabled:true];}

【讨论】:

    【解决方案4】:

    我正在改进 Lion 的答案。

    如果您使用的是 UITableViewAutomaticDimension,那么您必须从上到下设置串行约束。如果没有自动布局或适当的约束 UITableViewAutomaticDimension 将无法工作。所以你可以像这样管理这个东西:为你的文本视图设置顶部、底部、前导、尾随和固定高度约束。禁用 UITextview 的滚动功能,你就完成了。您不需要固定高度限制。

    【讨论】:

      【解决方案5】:

      在 Swift 4.2 中更新代码
      信用:http://www.swiftdevcenter.com/the-dynamic-height-of-uitextview-inside-uitableviewcell-swift/
      创建一个名为GrowingCell 的自定义单元格,在单元格中添加UITextView 并创建一个Outlet。在 ViewController 类的 UITableView 中注册此单元格。 你的视图控制器:

      import UIKit
      
      class ViewController: UIViewController {
      
          @IBOutlet weak var tableView: UITableView!
          override func viewDidLoad() {
              super.viewDidLoad()
              // Do any additional setup after loading the view, typically from a nib.
              let nib = UINib(nibName: "GrowingCell", bundle: nil)
              self.tableView.register(nib, forCellReuseIdentifier: "GrowingCell")
              self.tableView.tableFooterView = UIView()
              self.tableView.dataSource = self
          }
      }
      
      extension ViewController: UITableViewDataSource {
      
          func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
              return UITableView.automaticDimension
          }
      
          func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
              return 1
          }
      
          func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
              let cell = tableView.dequeueReusableCell(withIdentifier: "GrowingCell", for: indexPath) as! GrowingCell
              cell.cellDelegate = self
              return cell
          }
      
      }
      
      extension ViewController: GrowingCellProtocol {
          // Update height of UITextView based on string height
          func updateHeightOfRow(_ cell: GrowingCell, _ textView: UITextView) {
              let size = textView.bounds.size
              let newSize = tableView.sizeThatFits(CGSize(width: size.width,
                                                              height: CGFloat.greatestFiniteMagnitude))
              if size.height != newSize.height {
                  UIView.setAnimationsEnabled(false)
                  tableView?.beginUpdates()
                  tableView?.endUpdates()
                  UIView.setAnimationsEnabled(true)
                  // Scoll up your textview if required
                  if let thisIndexPath = tableView.indexPath(for: cell) {
                      tableView.scrollToRow(at: thisIndexPath, at: .bottom, animated: false)
                  }
              }
          }
      }
      

      现在移动到您的自定义GrowingCell 单元格并添加以下代码:

      import UIKit
      
      protocol GrowingCellProtocol: class {
          func updateHeightOfRow(_ cell: GrowingCell, _ textView: UITextView)
      }
      
      class GrowingCell: UITableViewCell {
      
          weak var cellDelegate: GrowingCellProtocol?
          @IBOutlet weak var textView: UITextView!
      
          override func awakeFromNib() {
              super.awakeFromNib()
              // Initialization code
              textView.delegate = self
          }
      
          override func setSelected(_ selected: Bool, animated: Bool) {
              super.setSelected(selected, animated: animated)
              // Configure the view for the selected state
          }
      }
      
      extension GrowingCell: UITextViewDelegate {
      
          func textViewDidChange(_ textView: UITextView) {
              if let deletate = cellDelegate {
                  deletate.updateHeightOfRow(self, textView)
              }
          }
      }
      

      更多详情:visit this full demo

      【讨论】:

        【解决方案6】:

        您需要禁用文本视图的滚动,以使tableViewCell根据文本视图的内容大小自动调整大小。

        【讨论】:

        • 这是让我自动调整大小的原因。
        【解决方案7】:

        不确定它是否可以帮助您,但我自定义了一个 UITextView,它适合内容高度作为其高度。

        这是你的 UITableViewCell 中的 TextView:

        final class ContentFittingTextView: UITextView {
            override var contentSize: CGSize {
                didSet {
                    invalidateIntrinsicContentSize()
                }
            }
        
            override var intrinsicContentSize: CGSize {
                self.layoutIfNeeded()
                return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
            }
        }
        

        从你的 UITableView:

        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 44
        

        【讨论】:

        • 这不起作用。您是否错过提及任何其他设置?
        猜你喜欢
        • 2011-06-20
        • 1970-01-01
        • 2012-10-19
        • 2018-04-09
        • 2014-05-19
        • 2012-10-18
        • 2013-09-02
        • 2019-10-12
        • 2015-12-09
        相关资源
        最近更新 更多