TableView单元格:约束更改冲突tableView.endUpdates()

时间:2018-12-22 12:16:24

标签: swift tableview constraints

我有一个用Swift编写的消息应用程序。


它确实有消息气泡:if the message is longer than 200 chars正在缩短。

每当用户单击邮件时,就会选择该邮件:

  • 如果消息被缩短,我将文本替换为原始的长文本:因此,我需要呼叫tableView.beginUpdates()tableView.endUpdates()
  • 此外,我必须使用UIView.animate()
  • 来更改timeLabel的高度限制

但两者似乎相互冲突,并制作了怪异的动画:(观看结尾)

https://youtu.be/QLGtUg1AmFw

代码:

func selectWorldMessage(indexPath: IndexPath) {

    if let cell = tableView.cellForRow(at: indexPath) as? WorldMessageCell {

        cell.messageLabel.text = data[indexPath.row].originalMessage
        self.lastContentOffsetY = self.tableView.contentOffset.y
        self.tableView.beginUpdates()
        UIView.animate(withDuration: duration) {


            cell.timeLabelHeightConstraint.constant = 18                

            cell.layoutIfNeeded()


        }

        self.tableView.endUpdates()
        self.lastContentOffsetY = nil
        cell.layoutIfNeeded()

         WorldMessageIdsStore.shared.nearby.saveCellHeight(indexPath: indexPath, height: cell.frame.size.height, expanded : true, depending: indexPath.section == 1 ? true : false )





    }
}
@objc func deselectSelectedWorldMessage(){
    if (currentSelectedIndexPath == nil){
        return
    }
    let indexPath = currentSelectedIndexPath!

    tableView.deselectRow(at: indexPath, animated: false)

    if let cell = tableView.cellForRow(at: indexPath) as? WorldMessageCell {

        cell.messageLabel.text = data[indexPath.row].shortenedMessage

        self.lastContentOffsetY = self.tableView.contentOffset.y
        self.tableView.beginUpdates()
        UIView.animate(withDuration: duration) {
            cell.timeLabelHeightConstraint.constant = 0                

            cell.layoutIfNeeded()



        }

        self.tableView.endUpdates()
        self.lastContentOffsetY = nil
        cell.layoutIfNeeded()


    }



    currentSelectedIndexPath = nil
}

是否可以同时对像元高度变化和约束变化进行动画处理?

我无法将self.tableView.beginUpdates()self.tableView.endUpdates()放在UIView.animate(){ ... }部分中,因为这会导致新出现的行闪烁。

。 。

更新1

因此,如果我将self.tableView.beginUpdates()self.tableView.endUpdates()放在UIView.animate(){ ... }内,则动画效果很好。但是正如我提到的,当出现新行时,它会导致闪烁。

视频:

https://youtu.be/8Sex3DoESkQ

更新2 !!

因此,如果我将UIview.animate的持续时间设置为0.3,则一切正常。我不太明白为什么。

2 个答案:

答案 0 :(得分:0)

此动画可能很粘。

我认为您在这里的主要问题是泡沫收缩的程度超过了应有的程度。如果以慢动画模式运行动画(顺便说一下,模拟器具有此选项,对于调试非常有用),您会注意到:

Bubble shrink

要解决此问题,您可以将标签设置为抗垂直内容压缩 较高,并且check标签也具有Hi优先级的顶部和底部约束,因此不会以这种方式被剪切。

https://medium.com/@abhimuralidharan/ios-content-hugging-and-content-compression-resistance-priorities-476fb5828ef

答案 1 :(得分:0)

尝试使用以下代码来克服滑动问题

tableView.scrollToRow(at: indexPath, at: UITableView.ScrollPosition.middle, animated: true)

替代解决方案 尝试使用这种漂亮的方法来更新动画,而不是使用beginUpdates()和endUpdates()方法

tableView.reloadRows(at: [indexPath], with: UITableView.RowAnimation.bottom )