Опциональные view в SwiftUI

12 июля 2021

Иногда нам нужно, чтобы какая-нибудь вьюха в SwiftUI была создана и отображена только в том случае, если какое-либо опциональное значение было не равно nil.
Например, давай предположим, что мы создаем некоторый HomeView, который условно содержит ProfileView, когда внутри нашего LogInManager содержит loggedInUser. До Swift 5.3 это было достаточно сложно реализовать с помощью стандартного SwiftUI API, но теперь мы просто можем использовать стандартную инструкцию if let для реализации этого:

struct HomeView: View {
    @ObservedObject var loginManager: LoginManager

    var body: some View {
        VStack {
            if let user = loginManager.loggedInUser {
    ProfileView(user: user)
}

            ...
        }
    }
}

Вторая опция, которая работает так же хорошо - это использовать оператор map для нашего значения loggedInUser, которое затем мы можем напрямую передать в наш ProfileView:

struct HomeView: View {
    @ObservedObject var loginManager: LoginManager

    var body: some View {
        VStack {
            loginManager.loggedInUser.map(ProfileView.init)
            ...
        }
    }
}

Третий и последний вариант - извлечение выше приведенного выражения (или нашего базового if let) в отдельное вычисляемое свойство, которое может послужить отличную службу при создании сложных вьюх, которые требуют большого количества вычислений для создания:

struct HomeView: View {
    @ObservedObject var loginManager: LoginManager

    var body: some View {
        VStack {
            profileView
            ...
        }
    }
    
    private var profileView: some View {
        loginManager.loggedInUser.map(ProfileView.init)
    }
}

В конце концов все три вышеперечисленные опции дают один и тот же результат, и остается выбор только за вами какой вариант подходит лучше всего в вашем случае.

Содержание