UIStackView中arrangedSubview的内容大小变化动画化

13

当一个排列的子视图的固有内容大小改变时,是否可以对其进行动画处理?

例如,假设我有一个排列的子视图,其中包含一个固定边缘的单个UILabel。该标签具有少量文本。新文本到来,比以前的文本更大。标签的固有内容大小现在更大。

我想这样做的目的是能够像这样进行动画处理:

 stackView.layoutIfNeeded()
 self.label.text = self.expanded ? textTwo : textOne
 UIView.animateWithDuration(0.3) { () -> Void in
     self.stackView.layoutIfNeeded()
 }

当前的 stackview 会从旧内容大小直接跳到新内容大小,忽略动画块。

当然,另一种方法是手动找出排列子视图的高度,并对该约束进行动画处理。如果可能的话,我想避免这种情况。


你尝试过调整父视图的布局吗? - jervine10
2个回答

13

找到了有效的方法:

label.text = expanded ? textOne : textTwo
UIView.animateWithDuration(0.4) { () -> Void in
    self.stackView.setNeedsLayout()
    self.stackView.layoutIfNeeded()
}

无法工作:

label.text = expanded ? textOne : textTwo
UIView.animateWithDuration(0.4) { () -> Void in
    self.stackView.layoutIfNeeded()
}

奇怪的是,改变内在内容大小并没有让stackView想要进行布局...


我无法通过这种方式使任何内容动画化。更改intrinsicContentSize没有任何作用,但是用布局约束替换它可以工作,尽管不是理想的解决方案。 - James P
确认。它在Xcode 14.2中工作! - RunesReader

0

假设您有一个自定义的UI元素,并更改其intrinsicContentSize

    ...
    var stackView: UIStackView!
    var yourUIElement: UIElement! // (any kind of ui element)
    
    UIView.animate(withDuration: 3, delay: 0) { [weak self] in
       guard let self = self else {return}
            self.yourUIElement.configure() // your configuration
            // in your case this will be label.text = expanded ? textOne : textTwo
            self.stackView.layoutIfNeeded()
            self.stackView.setNeedsLayout()
            self.yourUIElement.invalidateIntrinsicContentSize()
            // in your case this will be self.label.invalidateIntrinsicContentSize()
        }

这对我有用,希望对你有所帮助


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