Ios 在UITableViewCell中展开UITextView高度(阅读更多效果)

Ios 在UITableViewCell中展开UITextView高度(阅读更多效果),ios,swift,xcode,uitableview,animation,Ios,Swift,Xcode,Uitableview,Animation,当用户点击下面的“阅读更多”按钮时,我试图用动画扩展UITextView 我尝试了很多方法,并提出了几乎可行的解决方案: func readMore() { self.tableView.beginUpdates() cell.descTextViewHeightConstraint.constant = cell.descTextView.expectedHeight() self.tableView.endUpdates() } UItextView+高度 ext

当用户点击下面的“阅读更多”按钮时,我试图用动画扩展UITextView

我尝试了很多方法,并提出了几乎可行的解决方案:

func readMore() {
    self.tableView.beginUpdates()
    cell.descTextViewHeightConstraint.constant = cell.descTextView.expectedHeight()
    self.tableView.endUpdates()
}
UItextView+高度

extension UITextView {
    func expectedHeight() -> CGFloat {
        let textView: UITextView = UITextView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude))
        textView.font = self.font
        textView.text = self.text
        textView.sizeToFit()
        return textView.frame.height
    }
}
此解决方案可行,但有一个副作用-当动画完成时,UITableViewCell中的某些元素被隐藏(标题标签)

我还尝试在动画完成时调用tableView.reloadData(),这很有效,但有时也会产生副作用。

为什么不“播放”numberOfLines属性

对于一个项目,我做了类似的事情(还有一个旋转的UIImage箭头…)。所有内容都在自定义单元格类中:

func setExpanded(_ isExpanded: Bool) {
    if isExpanded {
        lblFullDescription.numberOfLines = 0
        UIView.animate(withDuration: Constants.NavigationBar.AnimationTime, animations: { [weak self] in
            self?.imgArrow.transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi))
        })

    } else {
        lblFullDescription.numberOfLines = 2
        UIView.animate(withDuration: Constants.NavigationBar.AnimationTime, animations: { [weak self] in
            self?.imgArrow.transform = CGAffineTransform(rotationAngle: CGFloat(0))
        })
    }
}
并将其添加到保存UITableView的ViewController中:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 42

您可以对单元格进行回调并更新其约束

func updateTableViewUIfor(indexPath: IndexPath) {
    self.tableView.beginUpdates()
    theCell.updateToExpanded() //get the cell and update it's constraints
    self.tableView.setNeedsDisplay()
    self.tableView.endUpdates()
}
你用

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
//... return required height
}

我在iOS 11和自动调整大小/大小的单元格方面遇到了一些问题。我不知道你的奇怪行为是什么,但在我的例子中,我确实将tableView
estimatedRowHeight
设置为一个大于我的最大单元格高度的值,并解决了它。

这个问题几乎每天都会被问到,这就是我创建这个示例项目的原因。调查一下,它非常简单。我在代码中发现了一个bug,造成了我提到的一个副作用(点击按钮“阅读更多”时未隐藏)。我在cellForRow函数中以编程方式创建了“阅读更多”按钮。问题是,当我多次滚动到该单元格时,每次都会创建按钮,而只有最后创建的按钮隐藏在该单元格上。@AuRis OP询问的“阅读更多”按钮/效果在哪里?@AwaisFayyaz示例项目显示了如何在键入其
UITextView
时更新单元格高度。基于该示例项目,您可以轻松实现“阅读更多”功能。这个项目并不是这个问题的答案。@filip.karas你能分享你的read more textview代码吗?我有不同的错误,我在问题评论中描述了它。但谢谢你的意见。可能会帮助其他人。我试过这种方法。它正在工作,但问题是它“从底部”设置动画。当我将行数设置为2时,我可以看到内容的前2行,这很好。但当我将“行数”设置为0时,我只能看到标签中内容的最后两行(而不是前两行),并且在动画期间,内容绑定到底部,因此我将最后显示内容的第一行。tableView.setNeedsDisplay没有帮助。动画运行后,仅tableView.reloadData()可用。