3

I have a ScooterReservationView class in SwiftUI:

...
@State var extensionIDs: [Int] = []

var body: some View {
    ...
    List(scooterExtensionVM.extensions, id: \.self) { scooterExtension in
            ScooterExtensionRow(_extension: scooterExtension, extensionIDs: self.$extensionIDs)
    }
...

The scooterExtensionVM.extensions array gets its value from an API request, the extensions are totally dynamic based on the backend API. Then I have the ScooterExtensionRow struct:

struct ScooterExtensionRow: View {

@EnvironmentObject var appState: AppState
@Binding var extensionIDs: [Int]

var scooterExtension: ScooterExtension
@State var isOn: Bool = true

init(_extension: ScooterExtension, extensionIDs: Binding<[Int]>) {
    self.scooterExtension = _extension
    self._extensionIDs = extensionIDs
}

var body: some View {
    HStack {
        Toggle(isOn: self.$isOn) {
            Text(scooterExtension.name)
        }
        .padding()
    }
}

}

My goal is to update extensionIDs array when the Toggle inside any of the ScooterExtensionRow view has changed. If any of the Toggle is switch on, I need to add the ScooterExtension's extension ID to that array, if its off, I need to remove the id from the array. This needs me for an API request later. (I need to collect all of the IDs of the enabled/toggled extensions)

The problem is: I cannot see in the docs any kind of callback action for the Toggle, where I can append/remove the value to/from the array, but maybe a callback is not the best way to do it in that Great SwiftUI World.

Can anyone help what is the best way to achieve this?

2
  • Is extensionIDs something that could fold into AppState in order to store (and publish) updates there? Commented Feb 28, 2020 at 23:27
  • I could put the extensionIDs into AppState, but I think its not solve my original problem, because I cannot append/delete elements to/from that array affter toggle switch Commented Feb 28, 2020 at 23:34

2 Answers 2

3

Assuming ScooterExtension has a property id, it can be done as follows:

Toggle(isOn: Binding<Bool>(get:{ self.isOn }, 
                set: { 
                    self.isOn = $0
                    if $0 { 
                       self.extensionIDs.append(self.scooterExtension.id) 
                    } else {
                       self.extensionIDs = self.extensionIDs.filter { $0 != self.scooterExtension.id }
                    }
                })) {
    Text(scooterExtension.name)
}
Sign up to request clarification or add additional context in comments.

Comments

0

Ah, I see what you are saying in your comment. How about a new container type for the ids. Something like

class ExtensionID: Identifiable, ObservableObject {
    let id: Int
    var isOn: Bool = true

    init(id: Int) {
        self.id = id
    }
}

Then you can bind the Toggle to the isOn property and conditionally display the ScooterExtensionRow (or whatever other changes you need based on a given id being off instead of actually missing from the array) based on this as well.

Does this make any sense?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.