ios – TableView在滚动到另一个时折叠单元格:奇怪的行为

ios – TableView在滚动到另一个时折叠单元格:奇怪的行为,第1张

概述我有一个带聊天气泡的tableView. 如果字符数超过250,则会缩短这些气泡 如果用户点击了气泡 >取消选择(缩短)先前的选择 >新选择扩展并显示整个内容 >新选择顶部约束更改(从0到4) 我想要实现什么? If a long bubble is selected already, but the user selects another bubble, I want the tableVie 我有一个带聊天气泡的tableVIEw.

如果字符数超过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)            }        }    }

更新1:添加了Github项目

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

我制作了一个小版本的应用程序,以便您可以查看并测试我的问题所在.如果有人能帮忙解决这个问题,我会非常感激! :C

解决方法 首先让我们通过“不滚动”来定义我们的意思 – 我们的意思是更少的细胞保持不变.所以我们想找到一个我们想成为锚细胞的细胞.从更改之前到更改之后,从单元格的顶部到屏幕顶部的距离是相同的.

var indexPathAnchorPoint:IndexPath?var offsetAnchorPoint:CG@R_403_5987@?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()

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

总结

以上是内存溢出为你收集整理的ios – TableView在滚动到另一个时折叠单元格:奇怪的行为全部内容,希望文章能够帮你解决ios – TableView在滚动到另一个时折叠单元格:奇怪的行为所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1033433.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-24
下一篇 2022-05-24

发表评论

登录后才能评论

评论列表(0条)

保存