SwiftUI - возврат в стек навигации не освобождает представление

Я хотел бы начать с выделения моей иерархии представлений. я простоFindUserView а также WelcomeView.

FindUserViewиспользуется для получения пользователей с сервера, если введенный адрес электронной почты существует. Если да, то он автоматически перенаправляет меня к следующемуWelcomeView где я могу ввести пароль и логин.

Я создал здесь репо и видео SwiftUI - Pop back не освобождает просмотр

Мой FindUserView: ---------------------------- а также WelcomeView:

-----------------

Нажав кнопку NEXT на FindUserView Я беру пользователя из базы данных:

func fetchUser(with email: String) {
        userService.getUser(with: email) { (result) in
            switch result {
            case .success(_):
                self.showActivityIndicator = false
                self.showingAlert = false
                self.showWelcomeView = true
                break
            case .failure:
                self.showingAlert = true
                break
            }
        }
    }

я использую NavigationView и программно показать WelcomeView путем изменения showWelcomeView указание выше:

NavigationLink(destination: WelcomeView(), isActive: $showWelcomeView) { EmptyView() }

Теперь я нахожусь на желанном взгляде WelcomeView.

Но когда я нажимаю эту кнопку и возвращаюсь, мой WelcomeView все еще существует.

Как я использую @EnvironmentObjectс наблюдаемым состоянием свойства я вижу, как оно отражается на уже отклоненном взгляде. Это правильное поведение? Или мне нужно освободить местоWelcomeViewкак-нибудь? Это приводит к утечкам памяти?

Я немного волнуюсь как в UIKit когда вы возвращаетесь в стек навигации, контроллер представления освобождается UINavigationControllerпутем автоматического удаления контроллера представления из массива. Как правильно вернуться в SwiftUI?

1 ответ

Решение

На самом деле неясно, является ли это дефектом или нет - представления SwiftUI являются значениями, поэтому для них нет функции освобождения. Это выглядит какNavigationViewпросто сохраняет что-то вроде переменной lastView до тех пор, пока она не будет заменена другой. Возможно, стоит отправить отзыв в Apple.

Между тем, вот решение, которое позволяет отложить создание реального вида назначения до ровно NavigationLink коснулся и очистил его (с любыми связанными ресурсами, такими как модель представления), когда представление удаляется из стека кнопкой Назад.

Протестировано с Xcode 11.4 / iOS 13.4

Презентатор вспомогательного прокси:

struct LinkPresenter<Content: View>: View {
    let content: () -> Content

    @State private var invlidated = false
    init(@ViewBuilder _ content: @escaping () -> Content) {
        self.content = content
    }
    var body: some View {
        Group {
            if self.invlidated {
                EmptyView()
            } else {
                content()
            }
        }
        .onDisappear { self.invlidated = true }
    }
}

Применение:

NavigationLink(destination: LinkPresenter { WelcomeView() }, 
    isActive: $showWelcomeView) { EmptyView() }
Другие вопросы по тегам