UITextView动画导致文本消失

5

我正在尝试通过改变transform来实现UITextView的动画效果。但在动画过程中会使文本消失。以下是我的测试代码。

class ViewController: UIViewController {
    let textView = UITextView()

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        textView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(textView)
        
        textView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        textView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
        textView.heightAnchor.constraint(equalToConstant: 300).isActive = true
        textView.backgroundColor = .systemOrange
        textView.text = "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"
        textView.textColor = .white

        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            let animator = UIViewPropertyAnimator(duration: 2, curve: .easeInOut, animations:  {
                self.textView.transform = CGAffineTransform(translationX: 0, y: 1000)
            })
            animator.startAnimation()
        }
    }
}

Demo

我尝试使用故事板,但结果相同。当我使用UIView.animate方法时,结果也是一样的。
为什么会这样?我想在文本上启用动画。

更新

let contraint = textView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
contraint.isActive = true

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    contraint.constant = 1000
    let animator = UIViewPropertyAnimator(duration: 2, curve: .easeInOut, animations:  {
        self.view.layoutIfNeeded()
    })
    animator.startAnimation()
}

我用这段代码进行了测试,得到了相同的结果。


@matt 我尝试了动画顶部约束,结果相同。我更新了我的问题。 - Paul
是的,我同意。该死!好吧,我有一个非常明显的建议:改为动画快照。抱歉,但这可能是最好的方法。我会举个例子。 - matt
@matt 是的。对快照进行动画处理非常完美。我之前测试过了。 - Paul
无论如何,还是将其作为答案给出。这并不是坏事;毕竟,这就是快照视图的用途,即为您提供一些可动画的内容。 - matt
1个回答

4

恐怕您只能对快照视图进行动画处理:

DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
    let v = self.textView.snapshotView(afterScreenUpdates: true)!
    v.frame = self.textView.frame
    self.view.addSubview(v)
    self.textView.isHidden = true
    let animator = UIViewPropertyAnimator(duration: 2, curve: .easeInOut, animations:  {
        v.frame.origin.y = 1000
    })
    animator.startAnimation()
}

我认为这不是一个糟糕的解决方案;毕竟这就是快照视图的用途。


是的。这很好。实际上,我在交互式过渡期间进行了动画变换。但是查找视图的所有UITextView子视图需要一些时间,所以我想避免这样做。 - Paul
哦,那听起来像是一个不同的问题。我实际上有一个很酷的工具,可以立即找到所有UITextView子视图。 :) https://dev59.com/olwY5IYBdhLWcg3w2Kwv#58138866 — 对我来说,你似乎没有真正提出正确的问题;显然,你想做的事情比你给出的例子要有趣得多。我很高兴你给出了简单的例子,因为这让复制问题变得非常容易;但更广泛地说,你显然想让文本视图可由用户拖动或类似的操作。 - matt
是的,这是一个不同的问题,我不知道为什么这个简单的例子不起作用。 - Paul
如果您认为文本视图在动画时应保持显示其文本,请向苹果提交错误报告。但显然它没有这样做,您已经证明了这一点;因此我们必须绕过它。 - matt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接