#ios #swift #swiftui #uikit
#iOS #swift #swiftui #uikit
Вопрос:
у меня есть контроллер навигации, который переходит к контроллеру представления, который переходит к uihostingcontroller. Как бы мне перейти к другому контроллеру представления из swift ui
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
self.window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
let navigationView = UINavigationController(rootViewController: PreviewViewVideoController())
navigationView.isToolbarHidden = true
self.window?.rootViewController = navigationView
self.window?.makeKeyAndVisible()
}
в контроллере предварительного просмотра видео
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch cards[indexPath.row] {
case .trans_human:
let controller = UIHostingControllerCustom(rootView: FilmOverviewView(overview: TransHumanOverview()))
self.navigationController?.pushViewController(controller, animated: true)
controller.navigationItem.title = cards[indexPath.row].rawValue
}
}
в filmOverviewView
struct FilmOverviewView: View {
var filmOverview: FilmOverview!
var imageResource: String!
init(overview: FilmOverview) {
filmOverview = overview
}
var body: some View {
ScrollView(Axis.Set.vertical, showsIndicators: false) {
VStack {
Image(filmOverview.imageResource)
.resizable()
.frame(width: UIScreen.main.bounds.width,
height: UIScreen.main.bounds.height / 2)
.overlay(StartButtonOverlay(), alignment: .bottom)
Button(action: {})
}
}
Как мне перейти от действия просмотра кнопки swiftui к новому контроллеру представления с использованием существующего стека навигации
Комментарии:
1. SwiftUI не работает с UINavigationController, поэтому вам необходимо продолжать использовать UIKit для навигации в таком сценарии.
2. как бы я это сделал с помощью кнопки в swiftui. я внес правку в код. допустим, у меня там есть кнопка, как бы вы это сделали из ее действия
Ответ №1:
Я бы ввел UINavigationController
в стек SwiftUI значения среды
struct NavigationControllerKey: EnvironmentKey {
static let defaultValue: UINavigationController? = nil
}
extension EnvironmentValues {
var navigationController: NavigationControllerKey.Value {
get {
return self[NavigationControllerKey.self]
}
set {
self[NavigationControllerKey.self] = newValue
}
}
}
затем в делегате представления таблицы введите его
let controller = UIHostingControllerCustom(rootView:
FilmOverviewView(overview: TransHumanOverview()
.environment(.navigationController, self.navigationController))
и теперь FilmOverviewView
мы можем это использовать
struct FilmOverviewView: View {
@Environment(.navigationController) var navigationController
// ... other code
var body: some View {
ScrollView(Axis.Set.vertical, showsIndicators: false) {
VStack {
// ... other code
Button("Demo") {
let controller = UIHostingControllerCustom(rootView:
SomeOtherView() // inject if needed again
.environment(.navigationController, self.navigationController)))
self.navigationController?.pushViewController(controller, animated: true)
}
}
}
Обновление: обновлен пользовательский контроллер хостинга
class UIHostingControllerCustom<V: View>: UIHostingController<V> {
override func viewWillAppear(_ animated: Bool) {
navigationController?.setNavigationBarHidden(true, animated: false)
}
}
Комментарии:
1. пусть контроллер = UIHostingControllerCustom(rootView: FilmOverviewView(обзор: TransHumanOverview()).environment(.NavigationController, self.NavigationController)) в табличном представлении выбрасывает Не удается преобразовать значение типа ‘some View’ в ожидаемый аргумент типа ‘FilmOverviewView’
2. Вам необходимо исправить обобщения в вашем пользовательском
UIHostingControllerCustom
классе.3. класс UIHostingControllerCustom:UIHostingController<FilmOverviewView>{ переопределить функцию viewWillAppear(_ animated: Bool) { NavigationController?.setNavigationBarHidden(true, animated: false) } } Что мне нужно изменить здесь