SwiftUI удаляет AnyView и отделяет определенные типыIOS

Программируем под IOS
Ответить
Anonymous
 SwiftUI удаляет AnyView и отделяет определенные типы

Сообщение Anonymous »

Итак, у меня есть представление, которое принимает viewModel, содержащее массив элементов, предоставляющих представления для построения тела в ForEach
И это выглядит так:

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

struct MainTabView: View {

@ObservedObject var viewModel: TabViewModel

var body: some View {
TabView {
ForEach(viewModel.tabs, id: \.title) { tab in
tab.view
.tabItem {
Image(systemName: tab.imageName)
Text(tab.title)
}
}
}
}
}

struct HomeView: View {
var body: some View {
VStack {
Text("Home")
.font(.largeTitle)
.padding()
Spacer()
}
}
}

class TabViewModel: ObservableObject {
@Published var tabs: [TabItem] = [
TabItem(title: "Home", imageName: "house.fill", view: AnyView(HomeView()))
]
}

struct TabItem {
let title: String
let imageName: String
let view: AnyView
}
Итак, я пытаюсь найти правильный способ отделить наши представления от конкретных типов, а также не использовать AnyView. Но кроме приведенного выше кода я не смог придумать компилируемый код или найти какое-либо полезное решение в Интернете.
Пожалуйста, может ли кто-нибудь объяснить мне, как работать с конкретными типами и внедрением зависимостей в SwiftUI в контексте приведенного выше кода?< /p>
Я пробовал использовать такие протоколы:

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

protocol TabViewProviding {
var title: String { get }
var imageName: String { get }
var tabView: any View { get }
}

protocol TabViewModelProviding: ObservableObject {
var tabs: [TabViewProviding] { get }
}
и заменил конкретные типы универсальными, но лучше всего я получил такие ошибки, как

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

Static method 'buildExpression' requires that 'Content' conform to 'AccessibilityRotorContent'
или просто связывать конкретные типы в разных местах.

#edit
поэтому, учитывая комментарий @lorem ipsum, я думаю, это лучший подход:

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

struct MainTabView: View {

@ObservedObject var viewModel: ViewModel

var body: some View {
TabView {
ForEach(viewModel.tabs, id: \.title) { tab in
createTabFor(tabType: tab.type)
.tabItem {
Image(systemName: tab.imageName)
Text(tab.title)
}
}
}
}

@ViewBuilder
func createTabFor(tabType: TabType) -> some View {
switch tabType {
case .recipes:
RecipeListView()
case .settings:
SettingsView()
}
}
}

protocol TabViewModelProviding: ObservableObject {
var tabs: [TabItemProviding] { get }
}

class TabViewModel: TabViewModelProviding {
@Published var tabs: [TabItemProviding] = [
TabItem(title: "Recipes", imageName: "wineglass.fill", type: .recipes),
TabItem(title: "Settings", imageName: "gearshape.fill", type: .settings)
]
}

enum TabType {
case settings
case recipes
}

protocol TabItemProviding {
var title: String { get }
var imageName: String { get }
var type: TabType { get }
}

struct TabItem: TabItemProviding {
let title: String
let imageName: String
let type: TabType
}
Если кто-то другой не укажет на какое-то улучшение, то это будет так.

Подробнее здесь: https://stackoverflow.com/questions/785 ... ific-types
Ответить

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

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

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

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

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