Как переключить переменную Bool в переменной @EnvironmentObject благодаря функции Toggle - PullRequest
0 голосов
/ 07 апреля 2020

Доброе утро всем,

Я пытаюсь создать приложение для подключенного дома. Итак, у меня есть класс light, который имеет свойство @Published var allLights: [Light] следующим образом:

struct Light: Identifiable {
    var id: Int
    var deviceName: String
    var intensity: Int
    // Should I remove the State wrapper ? 
    // Because Toggle only works with @State / Binding var...
    @State var mode: Bool 
}

class Lights: ObservableObject {
    @Published var allLights = [Light]()

    init() // I initialize this array using an API (thanks to SwiftyJSON)
}

Таким образом, в представлении я хотел бы иметь возможность изменять различные значения мои огни (только режим var на данный момент). Однако Toggle не изменяет значение режима @State var для каждого источника света ... Вот код для представления

struct LightsCollection: View {
    @EnvironmentObject var lightStore : Lights

    var body: some View {
        VStack {
            ForEach(lightStore.allLights) { light in
                HStack {
                    Text("\(light.id)")
                    Text("\(light.deviceName)")
                    Text("- \(light.intensity)")
                    Text("- " + String(light.mode))
                    Toggle(isOn: light.$mode) {
                        Text(light.mode ? "Switch off" : "Switch on")
                    }
                }
            }
        }
    }
}

Я уже читал много форумов, но ничего не поделать. .. Любая помощь будет оценена: -)

Ответы [ 2 ]

0 голосов
/ 07 апреля 2020

У вашей проблемы есть два решения: первое будет с struct, а второе с Class.


Использование Struct

Класс модели:

struct Light: Identifiable {
    var id: Int
    var deviceName: String
    var intensity: Int
    // State are used with View  
    var mode: Bool        
}

, и ваш View View будет выглядеть ниже, так как это массив struct, поэтому вам нужно получить к нему доступ по индексу и изменить его значение

var body: some View {
        VStack {
            ForEach(lightStore.allLights.indices) { index in
                HStack {
                    Text("\(self.lightStore.allLights[index].id)")
                    Text("\(self.lightStore.allLights[index].deviceName)")
                    Text("- \(self.lightStore.allLights[index].intensity)")
                    Text("- " + String(self.lightStore.allLights[index].mode))
                    Toggle(isOn: Binding(get: {
                        return self.lightStore.allLights[index].mode
                    }) { (value) in
                        //self.objectWillChange.send()
                        self.lightStore.allLights[index].mode = value
                    }) {
                        Text(self.lightStore.allLights[index].mode ? "Switch off" : "Switch on")
                    }
                }
            }
        }
    }

Используя Class

Модель класса:

class Light: Identifiable, ObservableObject {
    var id: Int
    var deviceName: String
    var intensity: Int
    var mode: Bool

    init(id: Int, deviceName: String, intensity: Int, mode: Bool) {
        self.id = id
        self.deviceName = deviceName
        self.intensity = intensity
        self.mode = mode
    }
}

и ваш класс просмотра будет как ниже

var body: some View {
        VStack {
            ForEach(lightStore.allLights) { light in
                HStack {
                    Text("\(light.id)")
                    Text("\(light.deviceName)")
                    Text("- \(light.intensity)")
                    Text("- " + String(light.mode))
                    Toggle(isOn: Binding(get: {
                        return light.mode
                    }) { (value) in
                        self.lightStore.objectWillChange.send() // you have to manually tell lightStore object to update
                        light.mode = value
                    }) {
                        Text(light.mode ? "Switch off" : "Switch on")
                    }
                }
            }
        }
    }
0 голосов
/ 07 апреля 2020

У меня что-то происходит со следующим (включая взлом):

Сначала объявите Light как класс, потому что структура не допускает изменения режима:

class Light: Identifiable {
var id: Int
var deviceName: String
var intensity: Int
var mode: Bool

init(id: Int, deviceName: String, intensity: Int, mode: Bool) {
    self.id = id
    self.deviceName = deviceName
    self.intensity = intensity
    self.mode = mode
}
}

, затем

struct LightsCollection: View {
@EnvironmentObject var lightStore : Lights
@State var refresh = false

var body: some View {
      ForEach(lightStore.allLights) { light in
            HStack {
                Text("\(light.id)")
                Text("\(light.deviceName)")
                Text("- \(light.intensity)")
                Text("- " + String(light.mode))
                Toggle(isOn: Binding(get: {
                    light.mode
                }, set: { newVal in
                    light.mode = newVal
                    self.refresh.toggle()
                })) {
                    Text(light.mode ? "Switch off" : "Switch on").accentColor(self.refresh ? .black : .black)
                }
            }
        }
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...