当服务器回调时,按SwiftUI按钮并转到下一个屏幕(下一个视图)

当服务器回调时,按SwiftUI按钮并转到下一个屏幕(下一个视图),swift,swiftui,swift5,Swift,Swiftui,Swift5,当我想按下ShowLoading指示器按钮,如果服务器返回Successful响应,则显示new view(新视图)时,我停留在非常简单的步骤 在UIKit中它非常简单,但在SwiftUI中我坚持这样做 我需要知道如何初始化/添加活动指示器我发现了一些很酷的例子。我可以将其作为let变量存储在我的视图sruct中吗 然后按按钮取消隐藏/设置指示器动画 通过我的RESTAPI服务发出服务器请求 等待一段时间,并在成功回调或错误消息上显示新视图 没什么特别难的,但我卡在这里的是一个按钮,它是我导航视

当我想按下ShowLoading指示器按钮,如果服务器返回Successful响应,则显示new view(新视图)时,我停留在非常简单的步骤

在UIKit中它非常简单,但在SwiftUI中我坚持这样做

  • 我需要知道如何初始化/添加活动指示器我发现了一些很酷的例子。我可以将其作为let变量存储在我的视图sruct中吗
  • 然后按按钮取消隐藏/设置指示器动画
  • 通过我的RESTAPI服务发出服务器请求
  • 等待一段时间,并在成功回调或错误消息上显示新视图
  • 没什么特别难的,但我卡在这里的是一个按钮,它是我导航视图的一部分。请帮我推到新屏幕

        Button(action: {
         // show indicator or animate
         // call rest api service
         // wait for callback and show next view or error alert
    
        })
    
    我找到了一些,但不知道如何正确使用它

    我根本不确定是否需要
    PresentationButton
    NavigationLink
    ,因为我已经有了一个简单的按钮,并且想按一下新的视图控制器

    非常类似的问题,但我没有发现它有用,因为我不知道如何一步一步地使用如何“创建隐藏的导航链接并绑定到该状态”

    编辑:
    我还发现这看起来像是我弄明白了如何导航。但仍然需要弄清楚当按下按钮时如何显示活动指示器。

    要在SwiftUI中的某个点显示您需要的任何内容,只需使用@State变量即可。 您可以根据需要使用任意数量的Bool。您可以切换新视图、动画

    例如:

    @State var showNextView = false
    @State var showLoadingAnimation = false
    
    Button(action: {
      self.showLoadingAnimation.toggle()
      self.makeApiCall()
    }) {
      Text("Show next view on api call success")
    }
    
    // Method that handle your api call
    func makeApiCall() {
      // Your api call
      if success {
        showLoadingAnimation = false
        showNextView = true
      }
    }
    
    至于动画,我建议您使用Lottie框架。您可以找到一些非常酷的动画:

    您可以在此处找到许多动画:

    您可以创建一个类,通过在项目中删除的JSON文件来实现Lottie动画:

    import SwiftUI
    import Lottie
    
    struct LottieRepresentable: UIViewRepresentable {
    
      let named: String // name of your lottie file
      let loop: Bool
    
      func makeUIView(context: Context) -> UIView {
        let view = UIView(frame: .zero)
    
        let animationView = AnimationView()
        let animation = Animation.named(named)
        animationView.animation = animation
        animationView.contentMode = .scaleAspectFit
        if loop { animationView.loopMode = .loop }
        animationView.play()
    
        animationView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(animationView)
    
        NSLayoutConstraint.activate([
          animationView.widthAnchor.constraint(equalTo: view.widthAnchor),
          animationView.heightAnchor.constraint(equalTo: view.heightAnchor)
        ])
    
        return view
      }
    
      func updateUIView(_ uiView: UIView, context: Context) { }
    }
    
    创建一个SwiftUI文件,以便在代码中使用乐透动画:

    // MARK: - Show LottieRespresentable as view
    struct LottieView: View {
    
      let named: String
      let loop: Bool
      let size: CGFloat
    
      var body: some View {
        VStack {
          LottieRepresentable(named: named, loop: loop)
            .frame(width: size, height: size)
        }
      }
    }
    
    最后的代码是这样的,带有NavigationLink,加载程序将从api调用的开始处开始,在api调用成功时结束:

    import SwiftUI
    
    //MARK: - Content view
    struct ContentView: View {
    
      @State var showMessageView = false
      @State var loopAnimation = false
    
      var body: some View {
        NavigationView {
          ZStack {
            NavigationLink(destination: MessageView(),
                           isActive: $showMessageView) {
              Text("")
    
              VStack {
                Button(action: {
                  self.loopAnimation.toggle()
                  self.makeApiCall()
                }) {
                  if self.loopAnimation {
                    Text("")
                  }
                  else {
                    Text("Submit")
                  }
                }
              }
    
              if self.loopAnimation {
                LottieView(named: "Your lottie json file name",
                           loop: self.loopAnimation,
                           size: 50)
              }
            }
            .navigationBarTitle("Content View")
          }
        }
      }
    
      func makeApiCall() {
        // your api call
        if success {
          loopAnimation = false
          showMessageView = true
        }
      }
    }
    

    要在SwiftUI中显示您需要的任何内容,只需使用@State变量。 您可以根据需要使用任意数量的Bool。您可以切换新视图、动画

    例如:

    @State var showNextView = false
    @State var showLoadingAnimation = false
    
    Button(action: {
      self.showLoadingAnimation.toggle()
      self.makeApiCall()
    }) {
      Text("Show next view on api call success")
    }
    
    // Method that handle your api call
    func makeApiCall() {
      // Your api call
      if success {
        showLoadingAnimation = false
        showNextView = true
      }
    }
    
    至于动画,我建议您使用Lottie框架。您可以找到一些非常酷的动画:

    您可以在此处找到许多动画:

    您可以创建一个类,通过在项目中删除的JSON文件来实现Lottie动画:

    import SwiftUI
    import Lottie
    
    struct LottieRepresentable: UIViewRepresentable {
    
      let named: String // name of your lottie file
      let loop: Bool
    
      func makeUIView(context: Context) -> UIView {
        let view = UIView(frame: .zero)
    
        let animationView = AnimationView()
        let animation = Animation.named(named)
        animationView.animation = animation
        animationView.contentMode = .scaleAspectFit
        if loop { animationView.loopMode = .loop }
        animationView.play()
    
        animationView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(animationView)
    
        NSLayoutConstraint.activate([
          animationView.widthAnchor.constraint(equalTo: view.widthAnchor),
          animationView.heightAnchor.constraint(equalTo: view.heightAnchor)
        ])
    
        return view
      }
    
      func updateUIView(_ uiView: UIView, context: Context) { }
    }
    
    创建一个SwiftUI文件,以便在代码中使用乐透动画:

    // MARK: - Show LottieRespresentable as view
    struct LottieView: View {
    
      let named: String
      let loop: Bool
      let size: CGFloat
    
      var body: some View {
        VStack {
          LottieRepresentable(named: named, loop: loop)
            .frame(width: size, height: size)
        }
      }
    }
    
    最后的代码是这样的,带有NavigationLink,加载程序将从api调用的开始处开始,在api调用成功时结束:

    import SwiftUI
    
    //MARK: - Content view
    struct ContentView: View {
    
      @State var showMessageView = false
      @State var loopAnimation = false
    
      var body: some View {
        NavigationView {
          ZStack {
            NavigationLink(destination: MessageView(),
                           isActive: $showMessageView) {
              Text("")
    
              VStack {
                Button(action: {
                  self.loopAnimation.toggle()
                  self.makeApiCall()
                }) {
                  if self.loopAnimation {
                    Text("")
                  }
                  else {
                    Text("Submit")
                  }
                }
              }
    
              if self.loopAnimation {
                LottieView(named: "Your lottie json file name",
                           loop: self.loopAnimation,
                           size: 50)
              }
            }
            .navigationBarTitle("Content View")
          }
        }
      }
    
      func makeApiCall() {
        // your api call
        if success {
          loopAnimation = false
          showMessageView = true
        }
      }
    }
    

    谢谢罗兰!作品超级酷!!!我刚到迅捷,我的行为真的很不寻常。但希望我能很快得到迅捷的概念。对于我来说,变量状态控制UI流是不寻常的。但是需要深入到迅捷,这怎么可能呢如果self.loopAnimation{}`@byJeevan,你能更具体地回答你的问题吗?我很乐意帮忙。亲爱的,“如果条件”在两个视图之间是不允许的。。。在上面的例子中,‘loopAnimation’谢谢罗兰!作品超级酷!!!我刚到迅捷,我的行为真的很不寻常。但希望我能很快得到迅捷的概念。对于我来说,变量状态控制UI流是不寻常的。但是需要深入到迅捷,这怎么可能呢如果self.loopAnimation{}`@byJeevan,你能更具体地回答你的问题吗?我很乐意帮忙。亲爱的,“如果条件”在两个视图之间是不允许的。。。在上述情况下,“循环动画”