为啥 NavigationView 中的动画从左上角开始?

Posted

技术标签:

【中文标题】为啥 NavigationView 中的动画从左上角开始?【英文标题】:Why does an animation in a NavigationView starts from the top left corner?为什么 NavigationView 中的动画从左上角开始? 【发布时间】:2020-11-21 15:52:47 【问题描述】:

我正在尝试在 SwiftUI 中创建一个简单的动画,我希望动画从中心顶部开始并结束到屏幕中心。 但是,正如您在视频中看到的,当我使用 NavigationView 时,动画从左上角开始:

这是我在这个例子中使用的代码:

struct ContentView: View 
    
    @State var show = false
    
    var body: some View 
        NavigationView 
            HStack 
                Text("Hello, world!")
                    .padding()
                    .background(Color.blue)
                    .offset(x: 0, y: show ? 0 : -30)
                    .animation(Animation.easeOut.delay(0.6))
                    .onAppear 
                            self.show = true
                    
                    .navigationTitle("Why?")
            
        
    

【问题讨论】:

【参考方案1】:

为什么 NavigationView 中的动画从左上角开始?

因为隐式动画会影响所有可动画属性,包括位置,创建时间为CGPoint.zero(即左上角)。

这种情况是通过将动画链接到依赖状态值来解决的,因此它仅在状态改变时才激活,因此所有可动画属性都不会受到影响。

这是您的情况的可能变体。使用 Xcode 12.1 / ios 14.1 测试。

struct ContentView: View 
    
    @State var show = false
    
    var body: some View 
        GeometryReader  gp in
            NavigationView 
                    HStack 
                         Text("Hello, world!")
                              .padding()
                              .background(Color.blue)
                              .offset(x: 0, y: show ? 0 : -gp.size.height / 2)
                              .animation(Animation.easeOut.delay(0.6), value: show)
                              .onAppear 
                                         self.show = true
                              
                              .navigationTitle("Why?")
                    
            
        
    

【讨论】:

谢谢!所以我什至不能使用 GeometryReader。我必须确定一个值并且它有效!【参考方案2】:

所以解决方案是在 animation 上使用 value 参数,它可以工作:

struct ContentView: View 
    
    @State var show = false
    
    var body: some View 
        NavigationView 
            HStack 
                Text("Hello, world!")
                    .padding()
                    .background(Color.blue)
                    .offset(x: 0, y: show ? 0 : -120)
                    .animation(Animation.easeOut.delay(0.6), value: show)
                    .onAppear 
                            self.show = true
                    
                    .navigationTitle("Why?")
            
        
    

【讨论】:

这对我有用。谢谢!

以上是关于为啥 NavigationView 中的动画从左上角开始?的主要内容,如果未能解决你的问题,请参考以下文章

出现 SwiftUI 意外动画

为啥我的 SwiftUI 应用程序在 `NavigationView` 中的 `navigationBarItems` 内放置 `NavigationLink` 后向后导航时崩溃?

打开 NavigationView 仅单击左上角图标,但不使用 swype 手势

为啥相同的 css 动画有时会不正确?

ScrollView + NavigationView 动画故障 SwiftUI

SwiftUI 如何在多级 NavigationView 中停止 List 的动画