Обработка EnvironmentObject в настройке нескольких окон / вкладок

#swift #swiftui

#swift #swiftui

Вопрос:

Как наилучшим образом обеспечить другой EnvironmentObject (или замену) для настройки нескольких вкладок / окон?

Допустим, у нас есть следующий MultipleWindow вид:

 struct MultipleWindow: View {
    @EnvironmentObject var environmentObject: EnvironmentObjectMultipleWindow
    var body: some View {
        VStack {

            ForEach(environmentObject.selectedPhoneSize.indices) { index in
                Button("Select (environmentObject.selectedPhoneSize[index].size)") {
                    environmentObject.selectedPhoneSize[environmentObject.selectedSizeIndex()].selected = false
                    environmentObject.selectedPhoneSize[index].selected = true
                
                }
                
            }
            
            ForEach(environmentObject.phones) { phone in
                if phone.size == environmentObject.selectedPhoneSize[environmentObject.selectedSizeIndex()].size {
                    Text("(phone.model): (phone.price)")
                }
            }
        }
    }
}
 

И EnvironmentObject:

 class EnvironmentObjectMultipleWindow: ObservableObject {
    @Published var selectedPhoneSize = phoneSizes
    @Published var phones = phoneArray
    
    func selectedSizeIndex() -> Int {
        return
            selectedPhoneSize.firstIndex {
                $0.selected == true
            } ?? 0
    }
    
}

struct PhoneSize: Identifiable {
    var id = UUID()
    var size: String
    var selected: Bool
}

let phoneSizes = [
    PhoneSize(size: "M", selected: true),
    PhoneSize(size: "X", selected: false),
    PhoneSize(size: "L", selected: false),
]

struct Phone: Identifiable {
    var id = UUID()
    var size: String
    var model: String
    var price: Int
}

let phoneArray = [
    Phone(size: "L", model: "New", price: 500),
    Phone(size: "X", model: "Old", price: 400),
    Phone(size: "X", model: "New", price: 600),
    Phone(size: "M", model: "New", price: 650)
]
 

и AppDelegate:

 @main
struct Testing_appApp: App {
    @StateObject var environmentObject = EnvironmentObjectMultipleWindow()

    var body: some Scene {
        WindowGroup {
            MultipleWindow().environmentObject(environmentObject)
        }
    }
}
 

Это работает, как и ожидалось — сначала вы выбираете размер модели, а затем просматриваете отфильтрованные результаты ForEach . Проблема в том, что когда вы открываете дополнительное окно (например, на iPad или macOS), любой сделанный вами выбор будет сделан во всех окнах. Я использую EnvironmentObject , потому что использую его во всем приложении. То же самое, что я использую, например, для выбора тегов, чтобы я мог изменить текущее представление из любого представления без каких-либо проблем. Есть ли способ сохранить все преимущества EnvironemntObject и представить разные EnvironmentObjectMultipleWindow для каждого окна или вкладки?

Ответ №1:

Вам необходимо создать объект на месте

 var body: some Scene {
    WindowGroup {
        MultipleWindow()
          .environmentObject(EnvironmentObjectMultipleWindow())  // << here !!
    }
}
 

Комментарии:

1. Привет, к сожалению, это не работает, поскольку я все еще получаю тот же environmentObject каким-то образом (протестировано как на iPad, так и на Mac)