如何禁用 NavigationView 推送和弹出动画

Posted

技术标签:

【中文标题】如何禁用 NavigationView 推送和弹出动画【英文标题】:How to disable NavigationView push and pop animations 【发布时间】:2019-12-09 20:13:52 【问题描述】:

鉴于这个简单的NavigationView

struct ContentView : View 
    var body: some View 
        NavigationView 
            VStack 
                NavigationLink("Push Me", destination: Text("PUSHED VIEW"))
            
        
    

当目标视图被推入/弹出堆栈时,是否有人找到了禁用NavigationView 动画的方法?

这在 ios2.0 之后的 UIKit 中就可以实现了!我认为从框架中要求并不过分。我在所有视图(即NavigationView 容器、目标视图、NavigationLink 等)上尝试了各种修饰符

这些是我尝试过的一些修饰符:

.animation(nil)
.transition(.identity)
.transaction  t in t.disablesAnimations = true 
.transaction  t in t.animation = nil 

没有任何区别。我也没有在EnvironmentValues 中找到任何有用的东西:-(

我是否遗漏了一些非常明显的东西,或者功能还不存在?

【问题讨论】:

【参考方案1】:

Xcode 11.3:

目前没有修改器可以禁用NavigationView 动画。

您可以使用您的结构init() 来禁用动画,如下所示:

struct ContentView : View 

    init()
        UINavigationBar.setAnimationsEnabled(false)
    

    var body: some View 
        NavigationView 
            VStack 
                NavigationLink("Push Me", destination: Text("PUSHED VIEW"))
            
        
    

【讨论】:

【参考方案2】:

我最近创建了一个名为swiftui-navigation-stack (https://github.com/biobeats/swiftui-navigation-stack) 的开源项目,其中包含NavigationStackView,这是一个模仿标准NavigationView 导航行为的视图,添加了一些有用的功能。例如,您可以使用 NavigationStackView 并按照 Kontiki 在问题中的要求禁用过渡动画。创建NavigationStackView 时,只需将.none 指定为transitionType

struct ContentView : View 
    var body: some View 
        NavigationStackView(transitionType: .none) 
            ZStack 
                Color.yellow.edgesIgnoringSafeArea(.all)

                PushView(destination: View2()) 
                    Text("PUSH")
                
            
        
    


struct View2: View 
    var body: some View 
        ZStack 
            Color.green.edgesIgnoringSafeArea(.all)
            PopView 
                Text("POP")
            
        
    

PushViewPopView 是两个允许你推送和弹出视图的视图(类似于 SwiftUI NavigationLink)。这是完整的示例:

import SwiftUI
import NavigationStack

struct ContentView : View 
    var body: some View 
        NavigationStackView(transitionType: .none) 
            ZStack 
                Color.yellow.edgesIgnoringSafeArea(.all)

                PushView(destination: View2()) 
                    Text("PUSH")
                
            
        
    


struct View2: View 
    var body: some View 
        ZStack 
            Color.green.edgesIgnoringSafeArea(.all)
            PopView 
                Text("POP")
            
        
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

结果是:

如果你们能和我一起改进这个开源项目,那就太好了。

【讨论】:

【参考方案3】:

首先您需要NavigationLink 响应的状态,然后在禁用动画的事务中设置该状态,如下所示:

struct ContentView : View 
    @State var isActive = false
    
    var body: some View 
        NavigationView 
            VStack 
                NavigationLink(isActive: $isActive, destination: 
                    Text("PUSHED VIEW")) 
                    Text("Push Me")
                
                Button("Navigate Without Animation") 
                    var transaction = Transaction()
                    transaction.disablesAnimations = true
                    withTransaction(transaction) 
                        isActive = true
                    
                
            
        
    

【讨论】:

以上是关于如何禁用 NavigationView 推送和弹出动画的主要内容,如果未能解决你的问题,请参考以下文章

如何将 UINavigationControllerDelegate 中的自定义过渡动画应用于特定的推送和弹出事件?

UIViewController 推送和弹出中的问题

java 堆栈 - 推送和弹出操作

golang 可以推送和弹出的intlist

TabBarController + NavigationController:推送和弹出问题

C-字符推送和弹出操作[关闭]