Как получить sh новый root вид с помощью SwiftUI без NavigationLink? - PullRequest
2 голосов
/ 09 февраля 2020

У меня есть экран входа. После того, как пользователь заполнил учетные данные, я хочу проверить их, а затем начать новый просмотр root, чтобы пользователь не смог вернуться к представлению входа в систему. В настоящее время у меня есть

Button(action: { 
// launch new root view here 
}, label: {Text("Login")}).padding()

Большинство ответов, которые я нашел в Интернете, используют навигационную ссылку, которую я не хочу. Некоторые другие ответы предлагают использовать AppDelegate на UIApplication.shared.delegate, что не работает для меня, потому что у меня есть SceneDelegate

Ответы [ 2 ]

2 голосов
/ 09 февраля 2020

Здесь возможен альтернативный подход, как заменить root полностью просмотреть ... с помощью уведомлений

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    let loginRootViewNotification = 
         NSNotification.Name("loginRootViewNotification") // declare notification
    private var observer: Any?               // ... and observer


    ...
    // in place of window creation ...
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = UIHostingController(rootView: contentView)

        observer = NotificationCenter.default.addObserver(forName: loginRootViewNotification, object: nil, queue: nil, using: { _ in
            let anotherRootView = AnotherRootView() 
            // create another view on notification and replace
            window.rootViewController = UIHostingController(rootView: anotherRootView)
        })

в нужном вам месте опубликовать необходимое уведомление

Button(action: { 
// launch new root view here 
   NotificationCenter.default.post(loginRootViewNotification)
}, label: {Text("Login")}).padding()
0 голосов
/ 27 февраля 2020

Другой подход с Уведомлениями - разместить наблюдателя внутри RootView и проверить наличие изменений в переменной, чтобы решить, какой View следует представить. Вот очень упрощенный пример:

struct RootView: View {

    @State var isLoggedIn: Bool = false

    var body: some View {
        Group {
            VStack{
                if isLoggedIn {
                    Text("View B")
                    Button(action: {
                        NotificationCenter.default.post(name: NSNotification.Name("changeLogin"), object: nil)
                    }) {
                        Text("Logout")
                    }
                } else {
                    Text("View A")
                    Button(action: {
                        NotificationCenter.default.post(name: NSNotification.Name("changeLogin"), object: nil)
                    }) {
                        Text("Login")
                    }
                }
            }
        }.onAppear {
            NotificationCenter.default.addObserver(forName: NSNotification.Name("changeLogin"), object: nil, queue: .main) { (_) in
                self.isLoggedIn.toggle()
            }
        }
    }

И загрузите RootView в Ваш rootViewController как обычно.

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    let contentView = RootView()
    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = UIHostingController(rootView: contentView)
        self.window = window
        window.makeKeyAndVisible()
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...