当 UITextView 大小发生变化时,如何调整 UITableViewCell 的大小?
Posted
技术标签:
【中文标题】当 UITextView 大小发生变化时,如何调整 UITableViewCell 的大小?【英文标题】:How do I make a UITableViewCell resize when a UITextView size changes? 【发布时间】:2019-06-20 23:30:06 【问题描述】:我遇到了 SnapKit 问题的自动布局。我在 UITableViewCell 中添加了一个 UITextView,并且我希望单元格在用户添加内容时随着文本视图的展开而展开。然而,实际上,当文本视图尝试扩展时,单元格约束会中断。这是我的代码:
TextFieldTableViewCell:
import UIKit
class TextFieldTableViewCell: FieldTableViewCell
let textView = EditableTextView()
override func setUpViews()
super.setUpViews()
setUpTextView()
private func setUpTextView()
contentView.addSubview(textView)
textView.setContentHuggingPriority(UILayoutPriority(rawValue: 10000), for: .vertical)
textView.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 10000), for: .vertical)
textView.snp.makeConstraints make in
make.top.equalTo(fieldLabel.snp.bottom).offset(margin)
make.leading.equalToSuperview().offset(margin)
make.trailing.equalToSuperview().offset(-margin)
make.bottom.equalToSuperview().offset(-margin)
EditableTextView:
import UIKit
class EditableTextView: UITextView
override func didMoveToSuperview()
super.didMoveToSuperview()
isEditable = true
isScrollEnabled = false
这是我的错误:
2019-06-20 18:23:10.276724-0500 Campaign Detective[1127:169808] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2019-06-20 18:23:10.278517-0500 Campaign Detective[1127:169808] [MC] Reading from public effective user settings.
2019-06-20 18:23:13.479469-0500 Campaign Detective[1127:169808] [LayoutConstraints] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(
"<NSContentSizeLayoutConstraint:0x2831c90e0 Campaign_Detective.EditableTextView:0x140813200'Yeah I\U2019ll call them later...'.height == 86 Hug:10000 CompressionResistance:10000 (active)>",
"<SnapKit.LayoutConstraint:0x2831f82a0@FieldTableViewCell.swift#37 UILabel:0x13fb03540.top == UITableViewCellContentView:0x13fb03830.top + 15.0>",
"<SnapKit.LayoutConstraint:0x2831d1740@TextFieldTableViewCell.swift#20 Campaign_Detective.EditableTextView:0x140813200.top == UILabel:0x13fb03540.bottom + 15.0>",
"<SnapKit.LayoutConstraint:0x2831d1920@TextFieldTableViewCell.swift#23 Campaign_Detective.EditableTextView:0x140813200.bottom == UITableViewCellContentView:0x13fb03830.bottom - 15.0>",
"<NSLayoutConstraint:0x2836b5040 'UIView-Encapsulated-Layout-Height' UITableViewCellContentView:0x13fb03830.height == 123.333 (active)>"
)
Will attempt to recover by breaking constraint
<NSContentSizeLayoutConstraint:0x2831c90e0 Campaign_Detective.EditableTextView:0x140813200'Yeah I'll call them later...'.height == 86 Hug:10000 CompressionResistance:10000 (active)>
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
单元格永远不会调整大小,因为UITableViewCellContentView:0x13fb03830.height
约束没有改变。系统不应该将其更改为新的计算高度吗?当我将.priority(.high)
设置为每个约束时,它仍然不起作用。
【问题讨论】:
【参考方案1】:以下行告诉引擎,当空间不足时,您希望 textView 缩小。这可能不是你想要的
textView.setContentHuggingPriority(UILayoutPriority(rawValue: 10000), for: .vertical)
如果你设置tableView.rowHeight = UITableView.automaticDimension
,用户编辑完成后你可以直接调用
tableView.beginUpdates()
tableView.endUpdates()
这应该重新计算单元格的高度并更新它
【讨论】:
【参考方案2】:如果没有一点帮助,表格视图和单元格不会自动调整大小。
像这样改变你的单元格:
// add the UITextViewDelegate
class TextFieldTableViewCell: FieldTableViewCell, UITextViewDelegate
let textView = EditableTextView()
// this will allow the cell to "call back" to the controller when the text is edited
var callback: ((String) -> ())?
// when the text changes, tell the controller to update the dataSource and the table layout
func textViewDidChange(_ textView: UITextView)
callback?(textView.text!)
override func setUpViews()
super.setUpViews()
setUpTextView()
private func setUpTextView()
contentView.addSubview(textView)
// set the delegate so textViewDidChange will be triggered on editing
textView.delegate = self
// use default Hugging and Compression
//textView.setContentHuggingPriority(UILayoutPriority(rawValue: 10000), for: .vertical)
//textView.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 10000), for: .vertical)
textView.snp.makeConstraints make in
make.top.equalTo(fieldLabel.snp.bottom).offset(margin)
make.leading.equalToSuperview().offset(margin)
make.trailing.equalToSuperview().offset(-margin)
make.bottom.equalToSuperview().offset(-margin)
然后,在您的控制器类中,将cellForRowAt
更改如下:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "TextFieldTableViewCell", for: indexPath) as! TextFieldTableViewCell
// assuming you have an array of strings for the text views
cell.textView.text = theData[indexPath.row]
// when the text in the cell is edited, the cell will "call back"
// and we can update the data source and tell the tableView to
// update its layout
cell.callback = (str) in
self.theData[indexPath.row] = str
self.tableView.beginUpdates()
self.tableView.endUpdates()
return cell
【讨论】:
以上是关于当 UITextView 大小发生变化时,如何调整 UITableViewCell 的大小?的主要内容,如果未能解决你的问题,请参考以下文章
在 UITableViewCell 中调整 UITextView 的大小时会发生奇怪的事情
当superView frameWidth 发生变化时,UIView 不会自动调整大小
当键盘出现在 iOS 7 中时如何调整 UITextview 的大小