SwiftUI - 动画过渡

Posted

技术标签:

【中文标题】SwiftUI - 动画过渡【英文标题】:SwiftUI - Animate transition 【发布时间】:2020-09-04 17:28:13 【问题描述】:

我在模态表上有一个退出按钮,可将用户带回登录屏幕。为此,我首先关闭工作表,然后使用 asyncAfter(deadline:) 设置一个环境变量,该变量会导致登录页面出现。一切正常,但是一旦关闭工作表,从工作表下的视图到登录页面的过渡非常不和谐。主要是因为没有。顶视图消失了,显示了登录视图。我知道我可以创建自定义过渡,但我不知道在哪里附加它。比如说,我想淡出工作表下方的视图。 (不过,我对任何形式的过渡都持开放态度!)

这是引导流量的结构:

struct ConductorView: View 
   @EnvironmentObject var tower: Tower
   let onboardingCompleted = UserDefaults.standard.bool(forKey: "FirstVisit")
    
   var body: some View 
      VStack 
         if tower.currentPage == .onboarding 
            Onboarding1View()
          else if tower.currentPage == .login 
            LoginView()
          else if tower.currentPage == .idle 
            LoginView()
         
      .onAppear
         if self.onboardingCompleted 
            self.tower.currentPage = .login
          else 
            self.tower.currentPage = .onboarding
         
      
   

这是工作表上的退出按钮:

Button(action: 
   self.presentationMode.wrappedValue.dismiss()
   DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) 
      self.tower.currentPage = .login
   
) 
   Text("Sign Out")

【问题讨论】:

【参考方案1】:

这是您复制代码的简化演示(我做了一些较长的延迟以使其模式可见)。当然,您需要通过更改过渡或动画类型等来调整它以满足您的需求。使用 Xcode 12 / ios 14 测试

class Tower: ObservableObject 
    enum PageType 
        case onboarding, login, idle
    
    @Published var currentPage: PageType = .onboarding


struct ConductorView: View 
   @EnvironmentObject var tower: Tower
   let onboardingCompleted = false

   var body: some View 
      VStack 
         if tower.currentPage == .onboarding 
            Onboarding1View()
          else if tower.currentPage == .login 
            Text("LoginView")
                .transition(.move(edge: .trailing))    // << here !!
          else if tower.currentPage == .idle 
            Text("IdleView")
         
      
      .animation(.default, value: tower.currentPage)   // << here !!
      .onAppear
         if self.onboardingCompleted 
            self.tower.currentPage = .login
          else 
            self.tower.currentPage = .onboarding
         
      
   



struct Onboarding1View: View 
   @EnvironmentObject var tower: Tower
    @Environment(\.presentationMode) var presentationMode
    @State private var isPresented = true
    var body: some View 
        Text("Login")
            .sheet(isPresented: $isPresented) 
                Button(action: 
                   self.presentationMode.wrappedValue.dismiss()
                   DispatchQueue.main.asyncAfter(deadline: .now() + 1) 
                      self.tower.currentPage = .login
                   
                ) 
                   Text("Sign Out")
                
            
    

【讨论】:

以上是关于SwiftUI - 动画过渡的主要内容,如果未能解决你的问题,请参考以下文章

滚动视图中的 SwiftUI 动画/过渡表现奇怪

如何在 SwiftUI 中动画/过渡文本值更改

SwiftUI - 过渡动画在 GeoReader 中不起作用?

SwiftUI:如何使用延迟在两个图像之间设置动画过渡?

NavigationView中的SwiftUI自定义动画过渡?

SwiftUI 动画:一些隐式过渡动画在 iOS 13 上被破坏了?