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];
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()
}
}
}
Until ios 13.x, there is no way provided by SwiftUI. So, I had same need so 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 which has a callback handler as its parameter. you can use this callback to dismiss the presented view.
It's worked well so far. looks 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 on his post.
UPDATE
Here is a full source code I am using so far.
https://gist.github.com/fullc0de/3d68b6b871f20630b981c7b4d51c8373