In this post, you will learn how to load a UIKit view into SwiftUI application. Consider a scenario that you want to display a loading indicator in a SwiftUI app. UIKit has an UIActivityIndicatorView
control that can be used to display loading indicators. Let’s see how we can load the UIActivityIndicatorView
in a SwiftUI application.
For the sake of this article, we are assuming that SwiftUI does not have a built-in loading indicator.
In order to represent a UIView in a SwiftUI app, we will use the UIViewRepresentable
protocol. UIViewRepresentable
protocol consists of two required functions.
makeUIView - This function is used to construct and return the UIView.
updateUIView - This function is used to update the uiView.
The implementation for LoadingIndicator is shown below:
import Foundation
import SwiftUI
import UIKit
struct LoadingIndicator: UIViewRepresentable {
typealias UIViewType = UIActivityIndicatorView
func makeUIView(context: Context) -> UIActivityIndicatorView {
let activityIndicatorView = UIActivityIndicatorView()
activityIndicatorView.color = UIColor.gray
return activityIndicatorView
}
func updateUIView(_ uiView: UIActivityIndicatorView, context: Context) {
uiView.startAnimating()
}
}
LoadingIndicator
is our SwiftUI representation of the UIActivityIndicatorView. The makeUIView
function simply constructs the UIActivityIndicatorView, sets the color and returns it. The updateUIView
function starts the animation.
Now, you can jump into the SwiftU view and use your new LoadingIndicator
. This is shown below:
struct ContentView: View {
var body: some View {
VStack {
LoadingIndicator()
}
}
}
If you run the app, you will see the loading indicator being displayed on the screen. In order to control the visibility of the loading indicator, we need to pass the loading state. This means we can dictate, when the loading indicator is animating and when it stops animating.
In the code below, we are passing a loading
variable to the LoadingIndicator view. The button is changing the state of the loading
variable from true
to false
after 2 seconds.
import SwiftUI
struct ContentView: View {
@State private var loading: Bool = false
var body: some View {
VStack {
LoadingIndicator(loading: loading)
Button("Get Data") {
loading = true
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
loading = false
}
}
}
}
}
Now, let’s update the LoadingIndicator
to utilize the new loading
argument.
import Foundation
import SwiftUI
import UIKit
struct LoadingIndicator: UIViewRepresentable {
var loading: Bool
typealias UIViewType = UIActivityIndicatorView
func makeUIView(context: Context) -> UIActivityIndicatorView {
let activityIndicatorView = UIActivityIndicatorView()
activityIndicatorView.color = UIColor.gray
return activityIndicatorView
}
func updateUIView(_ uiView: UIActivityIndicatorView, context: Context) {
if loading {
uiView.startAnimating()
} else {
uiView.stopAnimating()
}
}
}
And that’s it! Now when you press the button, the LoadingIndicator
will show the spinning image and after two seconds, it will stop animating.
I hope you liked the article. If you want to support my work then please check out my Udemy courses below: