Хотя мой другой ответ в настоящее время правильный, люди, вероятно, захотят сделать это сейчас.Мы можем использовать Environment
для передачи контроллера представления детям. Суть здесь
struct ViewControllerHolder {
weak var value: UIViewController?
}
struct ViewControllerKey: EnvironmentKey {
static var defaultValue: ViewControllerHolder { return ViewControllerHolder(value: UIApplication.shared.windows.first?.rootViewController ) }
}
extension EnvironmentValues {
// This will get/set the view controller directly. No need to worry about `.value` in use
var viewController: UIViewController? {
get { return self[ViewControllerKey.self].value }
set { self[ViewControllerKey.self].value = newValue }
}
}
Добавить расширение для UIViewController
extension UIViewController {
func present<Content: View>(style: UIModalPresentationStyle = .automatic, @ViewBuilder builder: () -> Content) {
// Must instantiate HostingController with some sort of view...
let toPresent = UIHostingController(rootView: AnyView(EmptyView()))
... but then we can reset that view to include the environment
toPresent.rootView = AnyView(
builder()
.environment(\.viewController, toPresent)
)
self.present(toPresent, animated: true, completion: nil)
}
}
И всякий раз, когда нам это нужно, используйте его:
struct MyView: View {
@Environment(\.viewController) private var viewController: UIViewController?
var body: some View {
Button(action: {
self.viewController?.present(style: .fullScreen) {
MyView()
}
}) {
Text("Present me!")
}
}
}