Last active
November 9, 2024 23:09
-
-
Save timothycosta/a43dfe25f1d8a37c71341a1ebaf82213 to your computer and use it in GitHub Desktop.
Using UIViewController via the SwiftUI Environment
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct ViewControllerHolder { | |
weak var value: UIViewController? | |
init(_ value: UIViewController?) { | |
self.value = value | |
} | |
} | |
struct ViewControllerKey: EnvironmentKey { | |
static var defaultValue: ViewControllerHolder { return ViewControllerHolder(UIApplication.shared.windows.first?.rootViewController ) } | |
} | |
extension EnvironmentValues { | |
var viewController: ViewControllerHolder { | |
get { return self[ViewControllerKey.self] } | |
set { self[ViewControllerKey.self] = newValue } | |
} | |
} | |
extension UIViewController { | |
func present<Content: View>(presentationStyle: UIModalPresentationStyle = .automatic, transitionStyle: UIModalTransitionStyle = .coverVertical, animated: Bool = true, completion: @escaping () -> Void = {}, @ViewBuilder builder: () -> Content) { | |
let toPresent = UIHostingController(rootView: AnyView(EmptyView())) | |
toPresent.modalPresentationStyle = presentationStyle | |
toPresent.rootView = AnyView( | |
builder() | |
.environment(\.viewController, ViewControllerHolder(toPresent)) | |
) | |
if presentationStyle == .overCurrentContext { | |
toPresent.view.backgroundColor = .clear | |
} | |
self.present(toPresent, animated: animated, completion: completion) | |
} | |
} |
@Environment(\.viewController) private var viewControllerHolder: ViewControllerHolder? private var viewController: UIViewController? { self.viewControllerHolder?.value }
with this code I'm getting error like
Key path value type 'ViewControllerHolder' cannot be converted to contextual type 'ViewControllerHolder?
Don't have time to test this but maybe try:
@Environment(\.viewController) private var viewControllerHolder: ViewControllerHolder
private var viewController: UIViewController? {
self.viewControllerHolder.value
}
Reading the gist, Line 14 defines viewController
to return a non-optional ViewControllerHolder
so I'm guessing that's the issue you're running into.
and how to dismiss it
its support for RTL?
Using UIViewControllerRepresentable to manage the make/update lifetime will fix the leak.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
with this code I'm getting error like
Key path value type 'ViewControllerHolder' cannot be converted to contextual type 'ViewControllerHolder?