SwiftUI中ScrollView中的动画过渡和内容
我并不是一个SwiftUI的老手,但我已经发布了一些中等复杂度的应用程序。尽管如此,我不能说我完全理解这一点,我希望有更深入的知识的人能够对这一问题有所了解: 我有一些内容要打开和关闭,这与.sheet()不同,但我希望对其进行更多的控制。下面是一些“重建”的代码,但它应该能够抓住本质:SwiftUI中ScrollView中的动画过渡和内容,swiftui,transition,swiftui-animation,Swiftui,Transition,Swiftui Animation,我并不是一个SwiftUI的老手,但我已经发布了一些中等复杂度的应用程序。尽管如此,我不能说我完全理解这一点,我希望有更深入的知识的人能够对这一问题有所了解: 我有一些内容要打开和关闭,这与.sheet()不同,但我希望对其进行更多的控制。下面是一些“重建”的代码,但它应该能够抓住本质: struct ContentView:View{ @国家私有变量isShown=false var body:一些观点{ GeometryReader{g in VStack{ ZStack(对齐:。顶部){
struct ContentView:View{
@国家私有变量isShown=false
var body:一些观点{
GeometryReader{g in
VStack{
ZStack(对齐:。顶部){
//此元素“保存”大小
//而内容是隐藏的
颜色。清晰
//要切换的内容
如果self.isShown{
滚动视图{
矩形()
.aspectRatio(1,contentMode:.fit)
.frame(宽度:g.size.width)//这是一个“变通方法”
}//滚动视图
.transition(.move(边:。底部))
.animation(.easeOut)
}
}//ZStack
//按钮以显示/隐藏内容
按钮(操作:{
self.isShown.toggle()
}) {
文本(self.isShown?“隐藏”:“显示”)
}
}//VStack
}//GeometryReader
}
}
它所做的是,它打开和关闭一些内容块(这里由ScrollView中的一个矩形表示)。当这种情况发生时,中的内容视图通过从底部移入一些动画进行转换。当再次点击按钮时,情况正好相反
这段特定的代码按预期工作,但仅因为这一行:
.frame(宽度:g.size.width)//这是一个“变通方法”
这反过来又需要一个额外的GeometryReader,否则,内容的宽度会被动画化,产生不想要的效果(我发现的另一个“修复”是使用.fixedSize()修饰符,但为了产生合理的效果,它需要像文本一样具有自身宽度的内容)
我向智者提出的问题是:是否有可能在不使用此类“修复”的情况下,在ScrollView中封装的内容中进行良好的转换?或者,是否有更优雅的解决方案
在@Asperi的回答之后,快速添加一个问题:内容应该保持动画效果。
你是我唯一的希望
–Baglan这里有一个解决方案(更新的正文
w/oGeometryReader
)。使用Xcode 11.4/iOS 13.4进行测试
var主体:一些视图{
VStack{
ZStack(对齐:。顶部){
//此元素“保存”大小
//而内容是隐藏的
颜色。清晰
//要切换的内容
如果self.isShown{
滚动视图{
矩形()
.aspectRatio(1,contentMode:.fit)
.动画(无)//您好,谢谢您的回答,这是一个有效的解决方案!我能看到的唯一问题是,我可能希望为内容设置动画。在实际项目中,有一些子视图以类似的方式显示动画或过渡,并且将动画设置为“零”会阻止这些。当然,您无法从代码中推断出这一点:)。不过,这是一个有效的答案,谢谢!我也有一个类似的问题,就是想在子视图中添加动画
var body: some View {
VStack {
ZStack(alignment: .top) {
// This element "holds" the size
// while the content is hidden
Color.clear
// Content to be toggled
if self.isShown {
ScrollView {
Rectangle()
.aspectRatio(1, contentMode: .fit)
.animation(nil) // << here !!
} // ScrollView
.transition(.move(edge: .bottom))
.animation(.easeOut)
}
} // ZStack
// Button to show / hide the content
Button(action: {
self.isShown.toggle()
}) {
Text(self.isShown ? "Hide" : "Show")
}
} // VStack
}