[英]SwiftUI animation/transition within scrollview behaving strange
我在 SwiftUI 中有一个带有多个元素的 ScrollView,其中一些元素可以在点击时展开。
struct ExpandingView: View {
@State var showContent = false
var body: some View {
VStack {
HStack {
Button(action: {withAnimation {
self.showContent.toggle()
}
}) {
Image(systemName: "chevron.right.circle")
}
Text("TITLE")
.padding(.leading, 10)
Spacer()
}
if showContent {
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras volutpat dapibus ante eget laoreet. Aenean lacus elit, auctor ut nisl id, fermentum pretium mi. Quisque lacus nisl, suscipit hendrerit est sed, congue dictum augue. Suspendisse semper viverra accumsan. Maecenas commodo turpis convallis nisl bibendum pharetra.")
.transition(AnyTransition.move(edge: .top).combined(with: .opacity))
}
}
}
}
struct Test: View {
var body: some View {
ScrollView {
ExpandingView()
ExpandingView()
ExpandingView()
Text("Some static text")
}
}
}
如果您尝试打开其中一个展开的文本,您会看到过渡并不顺畅,有点像跳跃,然后过渡开始。
所以这是我尝试过的:
ScrollView {
ExpandingView()
ExpandingView()
ExpandingView()
Text("Some static text")
}.animation(.spring())
它在打开过渡方面效果很好,使用 spring 效果甚至看起来更好,但是 spring animation 在视图出现时不播放整个滚动视图。
同样,如果我将 ScrollView 更改为 VStack,animation 不会在出现时播放,这很好,但我必须使用滚动视图。 所以对我来说最好的解决方案是保留 animation 来打开文本,但在视图出现时以某种方式将其删除。
这是可能的解决方案。 另请阅读内联评论。 使用 Xcode 11.4 / ISO 13.4 测试
struct ExpandingView: View {
@State var showContent = false
var body: some View {
VStack {
HStack {
Button(action: {
self.showContent.toggle()
}) {
Image(systemName: "chevron.right.circle")
}
Text("TITLE")
.padding(.leading, 10)
Spacer()
}
if showContent {
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras volutpat dapibus ante eget laoreet. Aenean lacus elit, auctor ut nisl id, fermentum pretium mi. Quisque lacus nisl, suscipit hendrerit est sed, congue dictum augue. Suspendisse semper viverra accumsan. Maecenas commodo turpis convallis nisl bibendum pharetra.")
.fixedSize(horizontal: false, vertical: true)
.transition(AnyTransition.move(edge: .top).combined(with: .opacity))
}
}
}
}
struct DemoExpandingView: View {
// initial nil to avoid initial animation
@State private var animation: Animation? = nil
var body: some View {
ScrollView {
VStack {
ExpandingView()
ExpandingView()
ExpandingView()
Text("Some static text")
}.animation(animation) // << needed to animate static section
}
.onAppear {
DispatchQueue.main.async {
// assign in-container animation `after` container rendered
self.animation = .default
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.