【问题标题】:iOS Autolayout: Oddly expand-animation of UITextView inside an UIScrollViewiOS Autolayout:UIScrollView 内 UITextView 的奇怪展开动画
【发布时间】:2020-07-18 09:39:40
【问题描述】:

我正在尝试为 UIScrollView 内的 UITextView 的高度约束设置动画。当用户点击“切换”按钮时,文本应该从上到下以动画形式出现。但不知何故,UIKit 在完整视图中消失了。

为了确保“动态”高度取决于内在内容大小,我将高度约束设置为零。

 @IBAction func toggle() {
    layoutIfNeeded()
    UIView.animate(withDuration: 0.6, animations: { [weak self] in

        guard let self = self else {
            return
        }

        if self.expanded {
            NSLayoutConstraint.activate([self.height].compactMap { $0 })
        } else {
            NSLayoutConstraint.deactivate([self.height].compactMap { $0 })
        }
        self.layoutIfNeeded()
    })
    expanded.toggle()
}

此示例的完整代码可在我的 GitHub 存储库中找到:ScrollAnimationExample

【问题讨论】:

  • 您使用UITextView 而不是UILabel 是否有原因?而且,您的目标是 iOS 13+ 或更早版本吗?
  • 嗨@DonMag,谢谢你的回答。 UITextView 没有理由。我们也可以使用多行UILabel。我们目前的目标是 iOS 11.2+,但正在考虑转到 iOS 13+。

标签: uiscrollview autolayout uikit uitextview


【解决方案1】:

正在查看您的 GitHub 存储库...

问题是由动画的view 引起的。您想在层次结构中的“最顶层”视图上运行 .animate()

为此,您可以创建ExpandableView 的新属性,例如:

var topMostView: UIView?

然后从您的视图控制器设置该属性,或者...

为了保持你的类被封装,让它找到最顶层的视图。将您的 toggle() 函数替换为:

@IBAction func toggle() {

    // we need to run .animate() on the "top" superview

    // make sure we have a superview
    guard self.superview != nil else {
        return
    }

    // find the top-most superview
    var mv: UIView = self
    while let s = mv.superview {
        mv = s
    }

    // UITextView has subviews, one of which is a _UITextContainerView,
    //  which also has a _UITextCanvasView subview.
    // If scrolling is disabled, and the TextView's height is animated to Zero,
    //  the CanvasView's height is instantly set to Zero -- so it disappears instead of animating.

    // So, when the view is "expanded" we need to first enable scrolling,
    //  and then animate the height (to Zero)
    // When the view is NOT expanded, we first disable scrolling
    //  and then animate the height (to its intrinsic content height)

    if expanded {
        textView.isScrollEnabled = true
        NSLayoutConstraint.activate([height].compactMap { $0 })
    } else {
        textView.isScrollEnabled = false
        NSLayoutConstraint.deactivate([height].compactMap { $0 })
    }

    UIView.animate(withDuration: 0.6, animations: {
        mv.layoutIfNeeded()
    })

    expanded.toggle()

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多