это просто, вам нужен доступ к значению, а не к его копии, предоставленной List
import SwiftUI
struct Package {
var flag: Bool
}
struct ContentView: View {
@State var arr = [Package(flag: true), Package(flag: false), Package(flag: true)]
var body: some View {
List(arr.indices, id:\.self) { (index) in
Text(self.arr[index].flag.description).onTapGesture {
self.arr[index].flag.toggle()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
или с помощью ObservableObject
import SwiftUI
struct Package: Identifiable {
let id = UUID()
var flag: Bool
}
class Model: ObservableObject {
@Published var arr = [Package(flag: true), Package(flag: false), Package(flag: true)]
}
struct ContentView: View {
@ObservedObject var model = Model()
var body: some View {
List(model.arr.indices) { (idx) in
Text(self.model.arr[idx].flag.description)
.onTapGesture {
self.model.arr[idx].flag.toggle()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
, который, как правило, тот же ... но в более сложном сценарии ios предпочтительнее
ОБНОВЛЕНИЕ на основе запроса Вы должны переопределить функцию строки
import SwiftUI
struct Package: Identifiable {
let id = UUID()
var flag: Bool
}
class Model: ObservableObject {
@Published var arr = [Package(flag: true), Package(flag: false), Package(flag: true)]
}
struct ContentView: View {
@ObservedObject var model = Model()
var body: some View {
List(model.arr.indices) { (idx) in
self.row(flag: self.$model.arr[idx].flag)
}
}
func row(flag: Binding<Bool>)-> some View {
Text(flag.wrappedValue.description)
.onTapGesture {
flag.wrappedValue.toggle()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Или второй вариант
import SwiftUI
struct Package: Identifiable {
let id = UUID()
var flag: Bool
}
class Model: ObservableObject {
@Published var arr = [Package(flag: true), Package(flag: false), Package(flag: true)]
}
struct ContentView: View {
@ObservedObject var model = Model()
var body: some View {
List(model.arr.indices) { (idx) in
self.row(idx: idx)
}
}
func row(idx: Int)-> some View {
Text(model.arr[idx].flag.description)
.onTapGesture {
self.model.arr[idx].flag.toggle()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
ОБНОВЛЕНИЕ с условной сортировкой
import SwiftUI
struct Package: Identifiable {
let id: Int
var flag: Bool
}
class Model: ObservableObject {
@Published var arr = [Package(id: 1, flag: true), Package(id: 3, flag: false), Package(id: 2, flag: true)]
@Published var ascending = false
var sorted: [Package] {
arr.sorted { (p0, p1) -> Bool in
let sort = (p0.id < p1.id)
return ascending ? !sort : sort
}
}
}
struct ContentView: View {
@ObservedObject var model = Model()
var body: some View {
VStack {
Toggle(isOn: $model.ascending) {
Text("ascending")
}.padding(.horizontal)
List(model.sorted.indices, id: \.self) { (idx) in
self.row(idx: idx)
}
}
}
func row(idx: Int)-> some View {
Text(verbatim: model.sorted[idx].flag.description + ": " + model.sorted[idx].id.description)
.onTapGesture {
if let i = self.model.arr.firstIndex (where: { (p) -> Bool in
self.model.sorted[idx].id == p.id
}) {
self.model.arr[i].flag.toggle()
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}