I have a situation where I would like to recreate previous UIKit
logic by displaying an Alert
during a long running operation that the user cannot interact with.
Previously in UIKit, it would be this simple:
import UIKit
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let alertController = UIAlertController(title: "Loading",
message: nil,
preferredStyle: .alert)
present(alertController, animated: true, completion: nil)
}
}
And it looks like this:
A simple SwiftUI
based version can be created as such:
import SwiftUI
struct ContentView: View {
@State private var isLoading = true
var body: some View {
Text("Hello")
.modifier(LoadingAlert(isPresented: $isLoading))
}
}
struct LoadingAlert: ViewModifier {
@Binding var isPresented: Bool
func body(content: Content) -> some View {
content
.alert(isPresented: $isPresented) {
Alert(title: Text(NSLocalizedString("Loading", comment: "")),
dismissButton: .none)
}
}
}
Whether I use nil
or .none
as the dismissButton
argument, or completely omit the line, it will use a default OK
button, and produce this:
I did modify the Alert
arguments, sending in a button with an empty title
, but this is the result, which is not as clean as I would like:
dismissButton: .default(Text("")))
Based on what I have seen, it does not appear that the Alert in SwiftUI supports what I want, based upon inspecting its initializers.
/// Creates an alert with one button.
public init(title: Text, message: Text? = nil, dismissButton: Alert.Button? = nil)
/// Creates an alert with two buttons.
///
/// - Note: the system determines the visual ordering of the buttons.
public init(title: Text, message: Text? = nil, primaryButton: Alert.Button, secondaryButton: Alert.Button)
For this project, the goal is to fully utilize SwiftUI, but it appears this is a scenario where we cannot get the desired result.
My take is either we will have to pull in a UIKit based AlertController
, or use a different effect to indicate status. However, I'd love to be wrong here.