我正在尝试在多行上添加展开/折叠动画Text,但我的行为很奇怪。
下面是这个问题的 gif。我设置了缓慢的动画以使其清晰。
https://www.dropbox.com/s/sx41g9tfx4hd378/expand-collapse-stack_overflow.gif
我正在对视图的高度属性进行动画处理,并且无论Text动画周期如何,它似乎都会立即转换为一行。这是一些代码:
struct ContentView: View {
@State var expanded = false
var body: some View {
VStack(spacing: 20) {
HStack {
Button(expanded ? "Colapse" : "Expand") {
withAnimation {
self.expanded.toggle()
}
}
}
VStack(spacing: 10) {
Text(bigText)
Text(bigText)
}
.frame(height: expanded ? .none : 0)
.clipped()
.background(Color.red)
Text("Thist is another text underneath the huge one. ")
.font(.system(.headline))
.foregroundColor(.red)
Spacer()
}
}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试了很多其他的东西,这是目前最接近所需的输出,这与UIStackView在 UIKit 中为 a 内的标签设置动画相同。
有没有办法正确地做到这一点?这是一个错误吗?通常问题来自开发人员,但我注意到,如果我使用动画,则DisclosureGroup在展开时动画会起作用,但在折叠时则没有动画。那么这实际上可能是多行的限制Text?
非常感谢。
好吧,问题是我们在nil和之间对帧进行动画处理0,但对于内部文本项,仅传输边缘值。
要解决这个问题,应该完成两个步骤:
这是一个方法演示。使用 Xcode 13 / iOS 15 准备
注意:在模拟器中激活慢速动画以获得更好的可见性
let bigText = """
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
"""
struct ContentView: View {
// we need `true` on construction (not visible) to calculate
// max content height
@State var expanded = true // << required initial true !!
@State private var maxHeight: CGFloat?
var body: some View {
VStack(spacing: 20) {
HStack {
Button(expanded ? "Colapse" : "Expand") {
withAnimation {
self.expanded.toggle()
}
}
}
VStack(spacing: 10) {
Text(bigText)
Text(bigText)
}
.background(GeometryReader { // read content height
Color.clear.preference(key: ViewHeightKey.self,
value: $0.frame(in: .local).size.height)
})
.onPreferenceChange(ViewHeightKey.self) {
if nil == self.maxHeight {
self.maxHeight = $0 // << needed once !!
}
}
.modifier(AnimatingFrameHeight(height: expanded ? maxHeight ?? .infinity : 0))
.clipped()
.background(Color.red)
Text("Thist is another text underneath the huge one. ")
.font(.system(.headline))
.foregroundColor(.red)
Spacer()
}
.onAppear {
// this cases instance redraw on first render
// so initial state will be invisible for user
expanded = false // << set if needed here !!
}
}
}
struct AnimatingFrameHeight: AnimatableModifier {
var height: CGFloat = 0
var animatableData: CGFloat {
get { height }
set { height = newValue }
}
func body(content: Content) -> some View {
content.frame(height: height)
}
}
struct ViewHeightKey: PreferenceKey {
static var defaultValue: CGFloat { 0 }
static func reduce(value: inout Value, nextValue: () -> Value) {
value = value + nextValue()
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
554 次 |
| 最近记录: |