Как сохранить состояние просмотра при переключении между совершенно разными макетами SwiftUI?IOS

Программируем под IOS
Ответить
Anonymous
 Как сохранить состояние просмотра при переключении между совершенно разными макетами SwiftUI?

Сообщение Anonymous »

Мое приложение использует разные макеты в зависимости от ориентации устройства. Например:
  • в портретной ориентации: макет на основе TabView
  • в альбомной ориентации: макет в стиле NavigationSplitView
При переключении между этими макетами содержимое (SubView) и его @StateObject не должны сбрасываться.
Изменяться должен только внешний макет — внутреннее представление должно сохранять свое состояние.
Что лучше и самый безопасный способ добиться этого?
Это работает, когда я создаю ViewModel в корне и внедряю ее:

Код: Выделить всё

struct SubView: View {
@ObservedObject var viewModel: ViewModel
...
}

struct RootView: View {
@State var useTabLayout = true
@StateObject var subViewModel = SubView.ViewModel()

var body: some View {
VStack {
Toggle("TabLayout", isOn: $useTabLayout)

if useTabLayout {
LayoutA {
SubView(viewModel: subViewModel)
}
} else {
LayoutB {
SubView(viewModel: subViewModel)
}
}
}
}
}
Однако для этого требуется, чтобы RootView знал и управлял ViewModel SubView, что может оказаться невозможным (например, для сторонних представлений). Я бы предпочел, чтобы SubView управлял собственным @StateObject:

Код: Выделить всё

struct SubView: View {
@StateObjekt var viewModel = ViewModel() // ViewModel created / owend by SubView
...
}

В этом случае RootView должен убедиться, что SubView создается только один раз:

Код: Выделить всё

// Option A — Keep a single instance
struct RootView: View {
@State var useTabLayout = true

private let subView = SubView()   // ← create only once

var body: some View {
VStack {
Toggle("TabLayout", isOn: $useTabLayout)

if useTabLayout {
LayoutA { subView }
} else {
LayoutB { subView }
}
}
}
}

// Option B — Fix identity with .id()
struct RootView: View {
@State var useTabLayout = true

var body: some View {
VStack {
Toggle("TabLayout", isOn: $useTabLayout)

if useTabLayout {
LayoutA { SubView().id("Subview") }
} else {
LayoutB { SubView().id("Subview") }
}
}
}
}
В моих тестах оба подхода работают, но это не доказывает, что они безопасны или рекомендованы.
Вопрос
Являются ли эти подходы правильными и безопасными?
Как лучше всего сохранять @StateObject при переключении между двумя совершенно разными макетами в SwiftUI?

Подробнее здесь: https://stackoverflow.com/questions/798 ... -swiftui-l
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»