Swift / 如何使用具有动态高度的 UITextView INSIDE UITableViewCell 与动态高度

Posted

技术标签:

【中文标题】Swift / 如何使用具有动态高度的 UITextView INSIDE UITableViewCell 与动态高度【英文标题】:Swift / how to use UITextView with dynamic height INSIDE UITableViewCell with dynamic height 【发布时间】: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 的高度不会。我该如何改变呢?非常感谢您的帮助。

【问题讨论】:

检查这个问题:- ***.com/questions/37014919/… 【参考方案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/

【讨论】:

即使 *** 不希望人们只是发布链接,因为链接可能会关闭,这实际上帮助了我。 现在链接失效了:( 上述链接失效 此链接已重新上线,但我认为值得在这里总结其内容,因为它确实运行良好。此处列出的大多数其他答案只是拼图中的一部分。简而言之,禁用文本视图的滚动,确保您可以在文本视图上初始化您的值,以便它会调用 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

【讨论】:

这不起作用。您是否错过提及任何其他设置?

以上是关于Swift / 如何使用具有动态高度的 UITextView INSIDE UITableViewCell 与动态高度的主要内容,如果未能解决你的问题,请参考以下文章

Swift:tableView 行的高度,其 tableView 单元格具有动态行数的嵌套 tableView

UICollectionView 单元格在swift中使用约束固定宽度和动态高度

Swift如何获得UIScrollView动态高度

如何获得根据标签内容动态变化的 UIView 的高度 - Swift

如何使用 UIKit 在 Swift 5 中创建具有内在高度的 UITableView?

如何在 Swift 中使用 SnapKit 使 UIView 具有相等的宽度和高度?