【发布时间】:2019-01-20 16:52:52
【问题描述】:
我有一个带有聊天气泡的 tableView。
如果character count 是more than 250,则这些气泡会缩短
如果用户点击气泡
- 先前的选择被取消选择(缩短)
- 新的选择扩展并显示全部内容
- 新的选择顶部约束更改(从 0 到 4)
我想达到什么目标?
如果已经选择了一个长气泡,但用户选择了另一个气泡,我希望 tableView 滚动到新选择的气泡的位置。
我会分享一个关于它的视频
没有这种滚动,contentOffset 保持不变,看起来很糟糕。
(在视频中:右侧)
视频:
右:没有提到的滚动
左:滚动
问题来了:
在左侧,您可以注意到它有故障。
-
无缘无故出现随机鬼细胞。
-
有时它甚至会弄乱一些气泡的高度(视频中没有)
为什么会这样?
代码:
func bubbleTappedHandler(sender: UITapGestureRecognizer) {
let touchPoint = sender.location(in: self.tableView)
if let indexPath = tableView.indexPathForRow(at: touchPoint) {
if indexPath == currentSelectedIndexPath {
// Selected bubble is tapped, deselect it
self.selectDeselectBubbles(deselect: indexPath)
} else {
if (currentSelectedIndexPath != nil){
// Deselect old bubble, select new one
self.selectDeselectBubbles(select: indexPath, deselect: currentSelectedIndexPath)
} else {
// Select bubble
self.selectDeselectBubbles(select: indexPath)
}
}
}
}
func selectDeselectBubbles(select: IndexPath? = nil, deselect: IndexPath? = nil){
var deselectCell : WorldMessageCell?
var selectCell : WorldMessageCell?
if let deselect = deselect {
deselectCell = tableView.cellForRow(at: deselect) as? WorldMessageCell
}
if let select = select {
selectCell = tableView.cellForRow(at: select) as? WorldMessageCell
}
// Deselect Main
if let deselect = deselect, let deselectCell = deselectCell {
tableView.deselectRow(at: deselect, animated: false)
currentSelectedIndexPath = nil
// Update text
deselectCell.messageLabel.text = self.dataSource[deselect.row].message.shortened()
}
// Select Main
if let select = select, let selectCell = selectCell {
tableView.selectRow(at: select, animated: true, scrollPosition: .none)
currentSelectedIndexPath = select
// Update text
deselectCell.messageLabel.text = self.dataSource[select.row].message.full()
}
UIView.animate(withDuration: appSettings.defaultAnimationSpeed) {
// Deselect Constraint changes
if let deselect = deselect, let deselectCell = deselectCell {
// Constarint change
deselectCell.nickNameButtonTopConstraint.constant = 0
deselectCell.timeLabel.alpha = 0.0
deselectCell.layoutIfNeeded()
}
// Select Constraint changes
if let select = select, let selectCell = selectCell {
// Constarint change
selectCell.nickNameButtonTopConstraint.constant = 4
selectCell.timeLabel.alpha = 1.0
selectCell.layoutIfNeeded()
}
}
self.tableView.beginUpdates()
self.tableView.endUpdates()
UIView.animate(withDuration: appSettings.defaultAnimationSpeed) {
if let select = select, deselect != nil, self.tableView.cellForRow(at: deselect!) == nil && deselectCell != nil {
// If deselected row is not anymore on screen
// but was before the collapsing,
// then scroll to new selected row
self.tableView.scrollToRow(at: select, at: .top, animated: false)
}
}
}
更新 1:添加 Github 项目
链接: https://github.com/krptia/test2
我制作了一个小版本的应用程序,以便您查看和测试我的问题所在。如果有人可以帮助解决这个问题,我将不胜感激! :c
【问题讨论】:
-
当你滚动时,它会重绘单元格,如果你不处理单元格来存储它所处的状态,它将绘制初始状态。
-
@carbonr 感谢您的回复!我该怎么做才能使它顺利?:c
-
这里有一点很重要。您正在使用轻击手势识别器进行选择检测。是否在 tableView 上启用了单元格选择,您是否也在实现
UITableViewDelegate的didSelectRow方法? -
@Adeel 选择已启用,但我没有实现
didSelectRow方法。我创建了自己的“选择系统”:因为我只希望在用户完全点击气泡时进行选择(这就是我创建委托(针对bubbleTappedHandler)的原因,以及为什么我有currentSelectedIndexPath变量。实际上我不需要使用tableView.selectRow(at: ...)和tableView.deselectRow(at: ...),所以是的,我将删除那些行。