【问题标题】:Press SwiftUI button and go to the next screen (next view) when server callback服务器回调时按下 SwiftUI 按钮并转到下一个屏幕(下一个视图)
【发布时间】:2020-07-28 21:06:55
【问题描述】:

当我想按下按钮显示加载指示器并且如果服务器返回成功响应然后显示新视图时,我停留在非常简单的步骤

在 UIKit 中这很简单,但在 SwiftUI 中我坚持这样做。

  1. 我需要知道如何初始化/添加活动指示器我发现了一些很酷的例子here。我可以将它作为 let 变量存储在我的视图 sruct 中吗?
  2. 然后按按钮取消隐藏/动画指示器
  3. 通过我的 rest api 服务发出服务器请求
  4. 稍等片刻,显示有关成功回调或错误消息的新视图。

没什么特别难的,但我卡在这里的是一个按钮,它是我的 NavigationView 的一部分。请帮我推到新屏幕。

    Button(action: {
     // show indicator or animate
     // call rest api service
     // wait for callback and show next view or error alert

    })

我找到了一些link,但不知道如何正确使用它。

我完全不确定我是否需要 PresentationButtonNavigationLink,因为我已经有一个简单的 Button 并且想要推送新的视图控制器。

this one 非常相似的问题,但我没有发现它有用,因为我不知道如何逐步使用如何“创建隐藏的 NavigationLink 并绑定到该状态”

已编辑: 我还发现这个video answer 看起来我知道如何进行导航。但是仍然需要弄清楚如何在按下按钮时显示活动指示器。

【问题讨论】:

    标签: swift swiftui swift5


    【解决方案1】:

    要在 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 框​​架。你可以找到一些非常酷的动画:

    https://github.com/airbnb/lottie-ios

    你可以在这里找到很多动画:

    https://lottiefiles.com

    您可以创建一个类来通过您在项目中放置的 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 的新手,我的行为真的很不寻常。但希望我能尽快了解 swiftui 的概念。对我来说不同寻常的是,变量状态控制 UI 流程。但需要更深入地了解 swiftui
    • 这怎么可能?? ` if self.loopAnimation { }`
    • @byJeevan 你能更具体地谈谈你的问题吗?我很乐意提供帮助。
    • 亲爱的,'if condition' 不允许在 View ... 在上述情况下,'loopAnimation'
    猜你喜欢
    • 2018-02-11
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-11
    • 2012-06-12
    • 1970-01-01
    • 2017-09-19
    相关资源
    最近更新 更多