【问题标题】:SwiftUI conditional view will not animate/transitionSwiftUI 条件视图不会动画/过渡
【发布时间】:2020-03-22 15:46:26
【问题描述】:

我正在尝试使用.transition() 对视图进行动画/过渡。我使用来自here 的类似代码并将.transition() 放入两个条件视图。

struct Base: View {
    @State private var isSignedIn = false

    var body: some View {
        Group {
            if(isSignedIn){
                Home().transition(.slide)
            }else{
                AuthSignin(isSignedIn: self.$isSignedIn).transition(.slide)
            }
        }
    }
}

struct AuthSignin: View {
    @Binding var isSignedIn: Bool

    var body: some View {
        VStack {
            Button(action: {
                self.isSignedIn = true
            }) {
                Text("Sign In")
                    .bold()
                    .frame(minWidth: CGFloat(0), maxWidth: .infinity)
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(Color.white)
                    .cornerRadius(CGFloat(10))
            }.padding()
        }
    }
}

但是,每当我单击“登录”按钮(有或没有.transition())时,应用程序将冻结一秒钟,然后Home() 视图会突然出现,没有任何动画/过渡。我也尝试将self.isSignedIn = true 包装在withAnimation 中,但它仍然无法正常工作。有什么想法或有更好的方法吗?

【问题讨论】:

    标签: swift xcode animation transition swiftui


    【解决方案1】:

    将您的.transition 放在将要切换的视图的容器上,而不是每个条件视图上。这是我完成的一些代码中的一个简单示例(有效)。

    在需要有条件转换的主View中:

    import SwiftUI
    
    struct AppWrapperView: View {
    
      @State var showFirstRun:Bool = true
    
      var body: some View {
        ZStack {
          if (showFirstRun) {
            FirstRunView(showFirstRun: $showFirstRun)
          } else {
            Text("Some other view")
          }
        }
        .transition(.slide)
      }
    }
    

    然后,在视图中触发条件变化的某处:

    import SwiftUI
    
    struct FirstRunView: View {
    
      @Binding var showFirstRun:Bool
    
      var body: some View {
    
        Button(action: {
          withAnimation {
            self.showFirstRun = false
          }
        }) {
          Text("Done")
        }
      }
    }
    

    【讨论】:

    • 对我不起作用 :( 我试图模仿 Google Maps 应用程序,当您按下搜索字段时会出现带有淡入淡出(不透明度)过渡的叠加视图。所以它仅在应用到“过渡”时才有效second" 视图,仅用于呈现(在没有动画的情况下关闭),但在应用于 ZStack 时根本不起作用。
    • 可行的解决方案是将 zIndex 添加到您想要呈现的至少“第二”视图中,或者甚至更好地将其添加到所有 ZStack 视图中。似乎是一个错误。在这里找到它:stackoverflow.com/questions/57730074/…
    【解决方案2】:

    我必须将 if..else 语句放在 ZStack 容器中,而不是 Group。在我的情况下,似乎Group 是动画损坏的主要原因。另外,我将.transition.animation 一起应用于容器而不是视图。

    ZStack {
      if(isSignedIn){
        Home()
      } else {
        AuthSignin(isSignedIn: self.$isSignedIn)
      }
    }
    .transition(.slide)
    .animation(.easeInOut)
    

    【讨论】:

    • ZStack 而不是 Group 成功了 - 谢谢。
    • ZStack 替换Group 也解决了我的问题!谢谢你的提示! ?‍♂️
    • 您必须注意 .zIndex()。如果将多个视图放置到 ZStack 中,则可能会发生动画只会在出现时播放,而不会在消失时播放。原因是视图在 ZStack 中的位置。当一个视图被关闭时,它被放置在 ZStack 中所有其他视图的后面。为避免任何类型的动画出现问题,请设置 ZStack 中每个视图的 .zIndex。还要避免使用 0 作为索引。
    【解决方案3】:

    放 withAnimation before self.isSignedIn = true

    【讨论】:

    • 是的,我已经尝试过了,就像我提到的将 self.isSignedIn = true 包裹在 withAnimation 中的位置,但仍然如此。现在问题似乎是,每当加载未显示的新复杂视图(例如 Home())时,就会冻结 2 秒。因此没有动画。
    • 那么您应该向我们展示您的复杂主页视图。一定有问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    相关资源
    最近更新 更多