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.
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.
To show anything you need at some point in SwiftUI, simply use a @State variable. You can use as many of these Bool as you need. 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 you use the Lottie framework. You can find some really cool animations:
https://github.com/airbnb/lottie-ios
You can find many animations here:
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
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.