For some reason, the following code is displaying an Alert with three instances of the same button, none of which trigger the action (just a simple console output for an example) as expected:
Has anyone else experienced this? Any suggestions on a fix?
It's building on Xcode 11.2.1, for an iOS 13.0 target, then running on macOS (10.15.1) via Catalyst.
Update 1: This appears to be an issue specific to Catalyst. When the same code is run on an iPhone simulator, it shows one button and executes the action, as expected.
Update 2: The issue also wasn't fixed by updating to Xcode 11.3.1 and macOS 10.15.3.
public struct ContactUsView: View {
@ObservedObject private var contactUsVM: ContactUsViewModel
private var successAlert: Alert {
Alert(
title: Text("Email Sent"),
message: Text("Thanks for taking the time to reach out to us. We appreciate it!"),
dismissButton: .default(Text("OK")) {
self.dismissSelf()
}
)
}
public var body: some View {
Form {
// ...
}
.alert(isPresented: self.$contactUsVM.contactAttemptSucceeded) {
self.successAlert
}
}
public init() {
self.contactUsVM = ContactUsViewModel()
}
private func dismissSelf() {
print("Dismissing!")
}
}
class ContactUsViewModel: ObservableObject {
@Published var contactAttemptSucceeded: Bool = true
}
It seems that your code works fine on xCode 11.5 MacOs 0.15.4. If you run your example (I've just filled the hole in your code):
import SwiftUI
public struct ContactUsView: View {
@ObservedObject private var contactUsVM: ContactUsViewModel
private var successAlert: Alert {
Alert(
title: Text("Email Sent"),
message: Text("Thanks for taking the time to reach out to us. We appreciate it!"),
dismissButton: .default(Text("OK")) {
self.dismissSelf()
}
)
}
public var body: some View {
Form {
Text("Hello World")
}
.alert(isPresented: self.$contactUsVM.contactAttemptSucceeded) {
self.successAlert
}
}
public init() {
self.contactUsVM = ContactUsViewModel()
}
private func dismissSelf() {
print("Dismissing!")
}
}
class ContactUsViewModel: ObservableObject {
@Published var contactAttemptSucceeded: Bool = true
}
You'll see this:
This seems to be fixed on macOS Big Sur. Unfortunately, for those folks, who need to support macOS Catalina(me included), the only workaround is to create alert using UIAlertController.
The way I did that, is dispatching notification to SceneDelegate
instance, and presenting UIAlertController
on UIHostingController
:
NotificationCenter.default.addObserver(forName: .showMailUnavailableAlert, object: nil, queue: nil) { [weak self] _ in
let controller = UIAlertController(title: "Default email client is not configured.", preferredStyle: .alert)
controller.addAction(.init(title: "Ok", style: .cancel, handler: nil))
self?.window?.rootViewController?.present(controller, animated: true, completion: nil)
}
extension NSNotification.Name {
static let showMailUnavailableAlert = NSNotification.Name("Email not configured.")
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With