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中使用约束固定宽度和动态高度
如何获得根据标签内容动态变化的 UIView 的高度 - Swift