在 SwiftUI 中将视图添加到层次结构时如何动画过渡
Posted
技术标签:
【中文标题】在 SwiftUI 中将视图添加到层次结构时如何动画过渡【英文标题】:How to animate transition when adding view to hierarchy in SwiftUI 【发布时间】:2020-10-16 17:33:03 【问题描述】:我正在尝试构建“弹出框”视图的叠加层并为进出动画过渡。转出有效,但转入无效 - 添加弹出视图时,它会突然出现(错误),但删除弹出视图时,它会向右滑出(正确)。在此代码中将弹出框添加到视图层次结构时,如何使弹出框滑入(从右侧)?
ios 14 中的完整功能代码。
import SwiftUI
struct ContentView: View
var body: some View
Popovers()
struct Popovers : View
@State var popovers : [AnyView] = []
var body : some View
Button("Add a view ...")
withAnimation
popovers += [new()]
.blur(radius: 0 < popovers.count ? 8 : 0)
.overlay(ZStack
ForEach(0..<self.popovers.count, id: \.self) i in
popovers[i]
.frame(maxWidth: .infinity, maxHeight: .infinity)
.blur(radius: (i+1) < popovers.count ? 8 : 0)
.transition(.move(edge: .trailing)) // works only when popover is removed
)
func new() -> AnyView
let popover = popovers.count
return AnyView.init(
VStack(spacing: 64)
Button("Close")
withAnimation
_ = popovers.removeLast()
.font(.largeTitle)
.padding()
Button("Add")
withAnimation
popovers += [new()]
.font(.largeTitle)
.padding()
Text("This is popover #\(popover)")
.font(.title)
.foregroundColor(.white)
.fixedSize()
.background(Color.init(hue: 0.65-(Double(3*popover)/100.0), saturation: 0.3, brightness: 0.9).opacity(0.98))
)
struct ContentView_Previews: PreviewProvider
static var previews: some View
ContentView()
extension View
var asAnyView : AnyView
AnyView(self)
【问题讨论】:
【参考方案1】:解决方案是向容器添加动画。使用 Xcode 12 / iOS 14 测试。
struct Popovers : View
@State var popovers : [AnyView] = []
var body : some View
Button("Add a view ...")
withAnimation
popovers += [new()]
.blur(radius: 0 < popovers.count ? 8 : 0)
.overlay(ZStack
ForEach(0..<self.popovers.count, id: \.self) i in
popovers[i]
.frame(maxWidth: .infinity, maxHeight: .infinity)
.blur(radius: (i+1) < popovers.count ? 8 : 0)
.transition(.move(edge: .trailing))
.animation(.default)) // << add animation to container
func new() -> AnyView
let popover = popovers.count
return AnyView.init(
VStack(spacing: 64)
Button("Close")
_ = popovers.removeLast()
.font(.largeTitle)
.padding()
Button("Add")
popovers += [new()]
.font(.largeTitle)
.padding()
Text("This is popover #\(popover)")
.font(.title)
.foregroundColor(.white)
.fixedSize()
.background(Color.init(hue: 0.65-(Double(3*popover)/100.0), saturation: 0.3, brightness: 0.9).opacity(0.98))
)
【讨论】:
效果很好,但为什么它现在可以工作 - 为什么它可以用于转出但不能转入?以上是关于在 SwiftUI 中将视图添加到层次结构时如何动画过渡的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SwiftUI 中将滚动视图添加到屏幕的特定部分? [复制]
是否可以在 SwiftUI 中将 Button<Text> 添加到 Text 中?