简体   繁体   中英

loop on toggle on swiftUI

I'm beginner in swiftUI and i'd like to generate toggles from an array of a struct.

my struct:

struct Provider : Identifiable  {
    var id:Int
    var name:String
    var isOn:Bool 
}

and my view

import SwiftUI

struct ContentView: View {
    @State private var providers:[Provider] = [Provider(id: 8, name: "Netflix", isOn: true), Provider(id: 564,name:"SALTO",isOn: false), Provider(id: 350, name: "Apple Tv Plus", isOn: false)]
   
    var body: some View {
        VStack{
            ForEach (providers) {provider  in
                Toggle(isOn: .constant($provider.isOn), label: {
                Text("\(provider.name.capitalized)")
                })
           }
        }
    }   
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

I don't know where to put de binding symbol.

  • if I put this like this got an error: "Cannot find $provider in scope"
  • if I put before isOn: "Value of type Provider has no member $isOn "
  • if I put before providers in the ForEach: "Cannot convert value of type Binding<[Provider]> to expected argument type Range<Int> "

But If do:

VStack{
    Toggle(isOn: $providers[0].isOn, label: {
        Text("\(providers[0].name.capitalized)")
    })             
}

It's work as well. Thanks for your help.

In your last example, you got the basics of it -- the simplest way to be able to modifier that providers array is to have an index to it. Here are two ways to achieve that:

struct ContentView: View {
    @State private var providers:[Provider] = [Provider(id: 8, name: "Netflix", isOn: true), Provider(id: 564,name:"SALTO",isOn: false), Provider(id: 350, name: "Apple Tv Plus", isOn: false)]
    
    var body: some View {
        VStack {
            ForEach(providers.indices) { providerIndex  in
                Toggle(isOn: $providers[providerIndex].isOn) {
                    Text("\(providers[providerIndex].name.capitalized)")
                }
            }
        }
    }
}
struct ContentView: View {
    @State private var providers:[Provider] = [Provider(id: 8, name: "Netflix", isOn: true), Provider(id: 564,name:"SALTO",isOn: false), Provider(id: 350, name: "Apple Tv Plus", isOn: false)]
    
    var body: some View {
        VStack {
            ForEach(Array(providers.enumerated()), id: \.1.id) { (index,provider)  in
                Toggle(isOn: $providers[index].isOn) {
                    Text("\(provider.name.capitalized)")
                }
            }
        }
    }
}

The second is my preferred way, since you get the provider as one of the parameters. There are slight performance issues with huge collections, at which point you might want to explore indexed from Swift Algorithms .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM