我有一个带有聊天气泡的tableView。
如果character count
为more than 250
,则气泡会缩短
如果用户点击气泡
如果已经选择了一个长气泡,但是用户选择了另一个气泡,我希望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)
}
}
}
链接: https://github.com/krptia/test2
我制作了一个小版本的应用程序,以便您可以查看和测试我的问题所在。如果有人可以帮助解决这个问题,我将非常感激! :c
答案 0 :(得分:1)
首先让我们定义“不滚动”的含义-我们的意思是单元格更少或更多保持不变。因此,我们想要找到一个我们想要成为锚点单元的单元。从更改之前到更改之后,从单元格顶部到屏幕顶部的距离是相同的。
var indexPathAnchorPoint:IndexPath?
var offsetAnchorPoint:CGFloat?
func findHighestCellThatStartsInFrame() -> UITableViewCell? {
var anchorCell:UITableViewCell?
for cell in self.tableView.visibleCells {
let topIsInFrame = cell.frame.origin.y >= self.tableView.contentOffset.y
if topIsInFrame {
if let currentlySelected = anchorCell{
let isHigerUpInView = cell.frame.origin.y < currentlySelected.frame.origin.y
if isHigerUpInView {
anchorCell = cell
}
}else{
anchorCell = cell
}
}
}
return anchorCell
}
func setAnchorPoint() {
self.indexPathAnchorPoint = nil;
self.offsetAnchorPoint = nil;
if let cell = self.findHighestCellThatStartsInFrame() {
self.offsetAnchorPoint = cell.frame.origin.y - self.tableView.contentOffset.y
self.indexPathAnchorPoint = self.tableView.indexPath(for: cell)
}
}
在开始做事之前,我们称呼它。
func bubbleTappedHandler(sender: UITapGestureRecognizer) {
self.setAnchorPoint()
....
接下来,我们需要在进行更改后设置内容偏移,以使单元格移回它应该位于的位置。
func scrollToAnchorPoint() {
if let indexPath = indexPathAnchorPoint, let offset = offsetAnchorPoint {
let rect = self.tableView.rectForRow(at: indexPath)
let contentOffset = rect.origin.y - offset
self.tableView.setContentOffset(CGPoint.init(x: 0, y: contentOffset), animated: false)
}
}
接下来,我们在完成更改后将其命名。
self.tableView.beginUpdates()
self.tableView.endUpdates()
self.tableView.layoutSubviews()
self.scrollToAnchorPoint()
动画可能有点奇怪,因为同时进行了很多操作。我们将同时更改内容偏移量和单元格的大小,但是如果您将手指放在第一个可见的单元格旁边,则会看到它的正确位置。
答案 1 :(得分:0)
尝试在willDisplay
上使用此UITableViewDelegate
api
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if (indexPath == currentSelectedIndexPath) {
// logic to expand your cell
// you don't need to animate it since still not visible
}
}
答案 2 :(得分:0)
使用此代码替换bubbleTappedHandler的代码,然后运行并检查:
var headersConfig = {
headers: {
'Authorization': 'Basic ' + btoa(dbUser + ' : ' + dbPass)
}
};
return $http.get(url, headersConfig);
答案 3 :(得分:0)
您可以使用 tableView?.scrollToRow 。例如
let newIndexPath = IndexPath(row: 0, section: 0) // put your selected indexpath and section here
yourTableViewName?.scrollToRow(at: newIndexPath, at: UITableViewScrollPosition.top, animated: true) // give the desired scroll position to tableView
可用的滚动位置为。无, .top ,。中间, .bottom
答案 4 :(得分:0)
此故障是由于一个小错误。只需完成这两项操作,问题便会解决。
在`viewDidLoad
中设置tableView的rowHeight
和estimatedRowHeight
tableView.estimatedRowHeight = 316 // Value taken from your project. This may be something else
tableView.rowHeight = UITableView.automaticDimension
从您的代码中删除estimatedHeightForRowAt
和heightForRowAt
委托方法。