How to achieve what the following Objective-C code achieves with SwiftUI? I haven't been able to get a firm grasp on the ideas presented.
[self presentViewController:messageViewController animated:YES completion:nil];
How to achieve what the following Objective-C code achieves with SwiftUI? I haven't been able to get a firm grasp on the ideas presented.
[self presentViewController:messageViewController animated:YES completion:nil];
Until ios 13.x, there is no way provided by SwiftUI. As I had the same need, wrote a custom modifier of View to achieve it.
extension View {
func uiKitFullPresent<V: View>(isPresented: Binding<Bool>, style: UIModalPresentationStyle = .fullScreen, content: @escaping (_ dismissHandler: @escaping () -> Void) -> V) -> some View {
self.modifier(FullScreenPresent(isPresented: isPresented, style: style, contentView: content))
}
}
struct FullScreenPresent<V: View>: ViewModifier {
@Binding var isPresented: Bool
@State private var isAlreadyPresented: Bool = false
let style: UIModalPresentationStyle
let contentView: (_ dismissHandler: @escaping () -> Void) -> V
@ViewBuilder
func body(content: Content) -> some View {
if isPresented {
content
.onAppear {
if self.isAlreadyPresented == false {
let hostingVC = UIHostingController(rootView: self.contentView({
self.isPresented = false
self.isAlreadyPresented = false
UIViewController.topMost?.dismiss(animated: true, completion: nil)
}))
hostingVC.modalPresentationStyle = self.style
UIViewController.topMost?.present(hostingVC, animated: true) {
self.isAlreadyPresented = true
}
}
}
} else {
content
}
}
}
And, you can use it as the following.
.uiKitFullPresent(isPresented: $isShowingPicker, content: { closeHandler in
SomeFullScreenView()
.onClose(closeHandler) // '.onClose' is a custom extension function written. you can invent your own way to call 'closeHandler'.
})
content parameter of .uiKitFullPresent is a closure that has a callback handler as its parameter. you can use this callback to dismiss the presented view.
It's worked well so far. It looks a little bit tricky though.
As you may know, iOS 14 will bring us a method to present any view in the way you want. Check fullScreenCover() out.
Regarding presenting UIViewController written by Objective-C, it would be possible as Asperi mentioned in his post.
UPDATE
Here is the full source code I am using so far.
https://gist.github.com/fullc0de/3d68b6b871f20630b981c7b4d51c8373
UPDATE_2
Now, I'd like to say that it's not a good approach because the idea underlying doesn't actually seem to match well with the mechanism of SwiftUI.
As there is no provided related code, so in pseudo-code it would look like the following
struct YourParentView: View {
@State private var presented = false
var body: some View {
// some other code that activates `presented` state
SomeUIElement()
.sheet(isPresented: $presented) {
YourMessageViewControllerRepresentable()
}
}
}