Swift:在用户键入UITextView时,不断调整tableViewCell的大小 [英] Swift: Continuous resizing of tableViewCell while user types in a UITextView
问题描述
上下文:
我正在创建我的第一个应用程序,但是遇到了一个我不知道的问题.
I'm creating one of my first apps but I've ran into an issue I cannot figure out.
-
我有一个tableView,其中的单元格包装了很多UIElement.所有约束都是使用EasyPeasy库完成的,该库基本上只是设置自动布局约束(我也尝试过手动设置它们).有问题的UITextView受到左右,顶部和底部的各种数字的约束,我对它的高度或宽度没有任何限制.
I have tableView with cells packed with quite a few UIElements. All constraints are done using the EasyPeasy library which basically just sets auto layout constraints ( I have tried setting them manually also). The UITextView in question is constrained by various numbers to the left, right, top and bottom, I have no constraints on it for height or width.
:我使用在单元格自定义类中声明的委托属性,将每个单元格的textView委托都设置为self.我还用它的单元格indexPath.row标记了每个textView(在textViewDidChange方法中提供了 textView.tag
整数).
in cellForRowAt indexPath: I set the textView delegate for each cells textView to self, using a delegate property declared within the cells custom class. I also tag every textView with its cells indexPath.row (gives textView.tag
integer in textViewDidChange method).
问题/确认:
- 浏览了如此多的内容后,我发现了一些类似的问题,但是我无法使它们对我有用,因此我实现了其中的某些部分,这些部分使我的案子感到合乎逻辑.我认为与我的情况不同的问题在于,要使我的单元格设计正常工作,单元格必须具有
itemHeight
或更高的高度. - 我注意到,当我在textview中键入内容时,textview本身的高度会增加(甚至低于单元格边界,但到达该点时它不可见),但是单元格本身不会调整大小.
- 我尝试了一个仅包含textView的单元格,因此问题必须出在textViewDidchange或heightForRowAt indexPath方法上.
问题:
我在这里做错了什么?为什么当我在textView中键入内容时,单元格的高度没有动态变化?
func textViewDidChange(_ textView: UITextView) {
var newframe = textView.frame
newframe.size.height = textView.contentSize.height - textView.frame.size.height + itemHeight[textView.tag]
textView.frame = newframe
let ndxPath = IndexPath(row: textView.tag, section: 0)
let cell = tableView.cellForRow(at: ndxPath) as! EventsCell
cell.frame = CGRect(x: cell.frame.origin.x, y: cell.frame.origin.y, width: cell.frame.width, height: textView.frame.height)
tableView.beginUpdates()
tableView.setNeedsLayout() //have tried without this line
tableView.layoutIfNeeded() //have tried without this line
tableView.endUpdates()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if UITableViewAutomaticDimension > itemHeight[indexPath.row] {
return UITableViewAutomaticDimension
} else {
return itemHeight[indexPath.row]
}
}
TextView约束:
let containerView : UIView = {
let cv = UIView(frame: .zero)
cv.backgroundColor = .white
cv.translatesAutoresizingMaskIntoConstraints = false
cv.layer.cornerRadius = 7
return cv
}()
let eventText : GrowingTextView = { // GrowingTextView is a extension to a regular UITextView
let tv = GrowingTextView()
tv.allowsEditingTextAttributes = true
tv.isScrollEnabled = false
var delegate: UITextViewDelegate?
tv.textContainerInset = UIEdgeInsetsMake(1, 1, 0, 1)
tv.autoresizingMask = .flexibleHeight
tv.translatesAutoresizingMaskIntoConstraints = false
return tv
}()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
containerView.addSubview(eventText)
contentView.addSubview(containerView)
containerView .easy.layout([Height(CGFloat(95 * itemCount)), Left(8), Right(8)])
eventText .easy.layout([Left(77), Right(5), Top(90), Bottom(4)])
}
感谢您阅读我的帖子.
推荐答案
- 确定高度的约束应以如下方式布置:将
textView
直接附加到contentView
的顶部和底部,或者将其附加到连接到contentView
的顶部和底部,以便自动布局可以通过连接约束来确定高度. - 请确保您没有提及
textView
和禁用滚动的高度.让自动尺寸处理所有这些事情. - 现在您所需要做的就是在
textViewDidChange
上调用 - The constraints that determine the height should be laid out in such a way that the
textView
is attached directly to the top and bottom of thecontentView
or to views which are connected to the top and bottom of thecontentView
, so that autolayout can make out the height by connecting the constraints. - Make sure that you do not mention a height for the
textView
and disable scrolling. Let automatic dimension take care of all that. - Now all you need to do is call
tableView.beginUpdates()
andtableView.endUpdates()
ontextViewDidChange
-
您应该将添加的其他高度存储在单元格类中的变量中,以便在重新加载tableVIew时,单元格可以重新加载适当的高度.
You should store the additional height that you add in a variable in the cell class so the cells can reload an appropriate height when the tableVIew is reloaded.
tableView.beginUpdates()
和 tableView.endUpdates()
这是我的 repo ,它演示了相同的情况.
Here is my repo which demonstrates the same.
OP
您还应该更改textViewDidChange方法
You should also change textViewDidChange method
cell.frame = CGRect(x: cell.frame.origin.x, y: cell.frame.origin.y, width: cell.frame.width, height: textView.frame.height)
到
let newFrame = "originalCellHeight" - "originalTextViewHeight" + textView.contentSize.height
cell.frame = CGRect(x: cell.frame.origin.x, y: cell.frame.origin.y, width: cell.frame.width, height: newFrame )`
这篇关于Swift:在用户键入UITextView时,不断调整tableViewCell的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!