1

I stuck at the pretty simple step when I want to press on the button show loading indicator and if server returns success response then show new view

It's pretty straightforward in UIKit, but with SwiftUI I stuck to do this.

  1. I need to know how to init/add activity indicator I found some cool examples here. Can I just store it as a let variable in my view sruct?
  2. Then by pressing button Unhide/Animate indicator
  3. Make a server request via my rest api service
  4. Wait some time and show new view on success callback or error message.

Nothing super hard, but I stuck here is a button which is a part of my NavigationView. Please help me push to new screen.

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

    })

I found some link but not sure how to use it right.

Not sure I need PresentationButton or NavigationLink at all as I already have a simple Button and want to kind of push new view controller.

Very similar question to this one but I have not find it useful as I don't know how to use step by step how to "Create hidden NavigationLink and bind to that state"

EDITED: I also found this video answer looks like I figure out how to do navigation. But still need to figure out how to show activity indicator when button pressed.

1 Answer 1

5

To show anything you need at some point in SwiftUI, simply use a @State variable. You can use as many of these Bool as needed. You can toggle a new view, animation...

Example

@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
  }
}

As for the animation, I would suggest the use the Lottie framework. You can find some really cool animations:

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

You can find many animations here:

https://lottiefiles.com

And you can create a class to implement your Lottie animation via a JSON file that you dropped in your project:

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) { }
}

Create a SwiftUI file to use your lottie animation in your code:

// 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)
    }
  }
}

So the final code would look like this with a NavigationLink, and you will have your loader starting at the beginning of your api call, and ending when api call succeeds:

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
    }
  }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you Roland! works super cool!!! I am new at swiftui really unusual behaviour form me. But hope I will get the conception of swiftui soon. Unusually for me that variables states control UI flow. But need to dive deeper to swiftui
How's that possible ?? ` if self.loopAnimation { }`
@byJeevan Can you please be more specific on your question? I would be happy to help.
Dear, 'if condition' is not allowed in between View ... in the above case, 'loopAnimation'

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.