我目前正在开发一种功能,可以在键入时动态更改UITableView单元格的高度。因此,如果用户键入的项目扩展了单元格的当前最大宽度,则单元格的高度应该增加。我的专业TableViewCell包含一个TextView和一个UILabel,并且还连接到它下面的另一个单元格。因此,在一个TableView中有一个带有两个TableViewCell的TableView。我一直试图尝试解决方法,但到目前为止还没有任何工作。有没有人有任何概念性的想法来完成它?
答案 0 :(得分:3)
首先将tableView rowHeight设置为UITableViewAutomaticDimension
,在表格视图单元格中添加具有top,leading,bottom和trailing约束的UITextView。将textView.isEditable
设置为true
,将textView.isScrollEnabled
设置为false
,然后实现textView委托方法textViewDidChange
。当文本更改时,您需要报告以查看控制器以更新tableview,一种方法是通过委派。在视图控制器中实施表格视图单元格委托,您可以在其中调用tableView.beginUpdates()
和tableView.endUpdates()
。而已。下面是一个经过测试和运作的例子。
您的视图控制器:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, ExpandingTableViewCellDelegate {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.register(UINib(nibName: "ExpandingTableViewCell", bundle: nil), forCellReuseIdentifier: "ExpandingTableViewCellIdentifier")
tableView.rowHeight = UITableViewAutomaticDimension
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ExpandingTableViewCellIdentifier", for: indexPath) as! ExpandingTableViewCell
cell.delegate = self
return cell
}
// Expanding teable view cell delegate
func didChangeText(text: String?, cell: ExpandingTableViewCell) {
tableView.beginUpdates()
tableView.endUpdates()
}
}
你的手机:
import UIKit
protocol ExpandingTableViewCellDelegate: class {
func didChangeText(text: String?, cell: ExpandingTableViewCell)
}
class ExpandingTableViewCell: UITableViewCell, UITextViewDelegate {
@IBOutlet weak var textView: UITextView!
weak var delegate: ExpandingTableViewCellDelegate?
override func awakeFromNib() {
super.awakeFromNib()
textView.delegate = self
textView.isEditable = true
textView.text = "Start typing: ..."
textView.isScrollEnabled = false
}
func textViewDidChange(_ textView: UITextView) {
delegate?.didChangeText(text: textView.text, cell: self)
}
}
示例项目在此处:https://github.com/bavarskis/ExpandingTableViewCell.git
答案 1 :(得分:0)
当您要求概念性地了解正在发生的事情时,您可能希望在我的github页面中查看项目:
https://github.com/mpj-chandler/variableSizeTextTableView
该项目包含一个子类UITableViewController控制器,它也是文本视图的委托。主要功能如下:
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
var textFrame : CGRect = textView.frame
let newHeight : CGFloat = ceil(textView.contentSize.height)
if newHeight - textFrame.height > 0 {
textFrame.size.height = ceil(textView.contentSize.height)
textView.frame = textFrame
textView.setContentOffset(CGPoint(x: 0, y: 5), animated: false)
self.updateLayout(textView)
}
textView.selectedRange = NSRange(location: textView.text.characters.count, length: 0)
textView.becomeFirstResponder()
return true
}
func updateLayout(_ forTextView: UITextView) -> Void {
guard forTextView.tag < self.data.count else { return }
self.data[forTextView.tag] = forTextView.text
let newHeight : CGFloat = forTextView.frame.height
let oldHeight : CGFloat = self.tableView.cellForRow(at: IndexPath(row: forTextView.tag, section: 0))!.frame.height
self.heights[forTextView.tag] = newHeight + 2
UIView.animate(withDuration: 0.25, animations: {
for cell in self.tableView.visibleCells {
if let indexPath = self.tableView.indexPath(for: cell) {
if (indexPath as NSIndexPath).row > forTextView.tag {
cell.frame = CGRect(origin: CGPoint(x: cell.frame.origin.x, y: cell.frame.origin.y + forTextView.frame.height + 2 - oldHeight), size: CGSize(width: cell.frame.width, height: self.heights[(indexPath as NSIndexPath).row]))
}
else if (indexPath as NSIndexPath).row == forTextView.tag
{
cell.frame = CGRect(origin: cell.frame.origin, size: CGSize(width: cell.frame.width, height: self.heights[(indexPath as NSIndexPath).row]))
}
}
}
})
}
警告:这是用Swift 2编写的,但对Swift 4的翻译应该是微不足道的。此外,如果您希望表视图可编辑,那么引用带有标签的单元格并不是一个好主意,但希望您能获得要点。
希望它有所帮助。