gpt4 book ai didi

ios - 滚动到另一个 : weird behavior 时 TableView 折叠单元格

转载 作者:搜寻专家 更新时间:2023-10-31 19:35:45 24 4
gpt4 key购买 nike

我有一个带有聊天气泡的 tableView。


如果 character count 超过 250,这些气泡会缩短

如果用户点击气泡

  • 先前的选择被取消选择(缩短)
  • 新的选择扩展并揭示了全部内容
  • 新的选择顶部约束发生变化(从 0 到 4)

我想达到什么目的?

If a long bubble is selected already, but the user selects another bubble, I want the tableView to scroll to the position of the new selected bubble.

我会分享一个关于它的视频

没有这个滚动,contentOffset 保持不变,看起来很糟糕。

(视频中:右侧)


视频:

Right: without the mentioned scrolling

Left: with scrolling

https://youtu.be/_-peZycZEAE


问题来了:

在左侧,您可以注意到它有故障。

  • 无缘无故出现随机幽灵细胞。

  • 有时它甚至会弄乱一些气泡的高度(视频中没有)

为什么会这样?

代码:

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)
}
}

}

更新一:新增Github项目

链接: https://github.com/krptia/test2

我制作了一个小版本的应用程序,以便您可以查看和测试我的问题所在。如果有人可以帮助解决这个问题,我将不胜感激! :c

最佳答案

首先让我们定义“不滚动”的意思——我们的意思是单元格或多或少保持不变。所以我们想找到一个我们想成为 anchor 细胞的细胞。从更改之前到更改之后,从单元格顶部到屏幕顶部的距离是相同的。

var indexPathAnchorPoint: IndexPath?
var offsetAnchorPoint: CGFloat?

func findHighestCellThatStartsInFrame() -> UITableViewCell? {
return self.tableView.visibleCells.filter {
$0.frame.origin.y >= self.tableView.contentOffset.y
}.sorted {
$0.frame.origin.y > $1.frame.origin.y
}.first
}

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()

动画可能有点奇怪,因为同时发生了很多事情。我们正在同时更改单元格的内容偏移量和大小,但如果您将手指放在顶部可见的第一个单元格旁边,您会看到它最终位于正确的位置。

关于ios - 滚动到另一个 : weird behavior 时 TableView 折叠单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54278738/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com