Posted on April 21st 2020 by Chris Eidhof
In Swift Talk Episode 198, we made a wrapper around UIKit alerts.
SwiftUI provides a built-in API just for this: the alert method on View
allows us to present an alert to the user, and under the hood it almost certainly uses a UIAlertController
.
For our purposes, we wanted an alert controller with a text field. UIAlertController
supports this, but so far, SwiftUI’s built-in Alert
struct does not. To route around this limitation, we’ve found a hack that seems to work — for us at least! (we haven’t tested this in a project other than our own).
We’ll start by defining an API similar to SwiftUI’s builtin alert API. It will have the usual properties, and an action
parameter that gets called whenever the user presses either the OK or Cancel button.
Now for the hacky part. When we call alert
on a view, we wrap that view inside a custom UIViewControllerRepresentable
. Inside, we create a UIHostingController
for the view, so that we can call .present
on it.
To store the current alert controller we need to create a coordinator:
Finally, we need to show and hide the alert whenever our binding changes. SwiftUI will automatically observe the binding and call updateUIViewController(_:context:)
each time that happens. Inside, there are two code paths: when the binding’s value is true
but we’re not yet presenting the alert controller, we need to present it; when the binding’s value is false
but we are presenting the alert controller, we need to dismiss it.
Note that we’re setting the hosting controller’s root view in the first line of the updateViewController
method. This method will be called if our isPresented
binding for the alert changes, but also when something changes that affects the content of the alert wrapper. If we omit this first line, SwiftUI will no longer update the view inside the hosting controller.
Now we can use our text alert:
We hope that SwiftUI will catch up with UIAlertController
, making these kinds of hacks unnecessary. In the meantime, if anyone knows of a simpler way to do this, do let us know and we’ll update this post!
Here’s the full code.
Our SwiftUI Collection has 33 episodes and growing, with 8 public episodes. In our latest series, we port App Architecture‘s sample app from MVC to SwiftUI — the first episode is free to watch.
We wrap a UIKit alert in a SwiftUI-like API to present an alert with a text field.
Episode 198 · April 10, 2020
42 Episodes · 15h47min
Stay up-to-date with our newsletter or follow us on Twitter.
Nov 27th, 2020
30% on everything until Monday
Nov 23rd, 2020
How grids lay out their content.
Nov 9th, 2020
Flexibility Defined
Browse the Archive
objc.io publishes books, videos, and articles on advanced techniques for iOS and macOS development.
Learn
Follow
More