Измените цвет определенной кнопки внутри каждого цикла SwiftUI

#swiftui

Вопрос:

У меня есть код, который генерирует список кнопок. Чего я хочу, так это чтобы при нажатии кнопки эта кнопка меняла цвет. Проблема, с которой я сталкиваюсь, заключается в том, что код не позволяет мне выполнять workout.isActive.toggle (), поскольку «тренировка», по-видимому, является константой «let». Как я могу преодолеть эту проблему? Я все еще новичок в swift, поэтому буду признателен за любую помощь :).

 struct Workout: Identifiable {
    var id = UUID()
    var name: String
    var isActive: Bool

}

    struct Workout_builder: View {

var workouts = [
    Workout(name: "Bench Press", isActive: false),
    Workout(name: "Shoulder Press", isActive: false),
    Workout(name: "Incline Press", isActive: false),
    Workout(name: "Lateral Raises", isActive: false),
    Workout(name: "Tricep Cable", isActive: false),]
        
var body: some View {

    
    VStack {
        List {
            ForEach(workouts)  { workout in
                Button(action: {
                    workout.isActive.toggle()
                })
                {
                    Text(workout.name)
                        .foregroundColor(.black)
                        .background(workout.isActive ? Color(.white) : Color(.blue))
                    }
                }
            }
        }
    }
}
 

Ответ №1:

если вы используете SwiftUI 3.0, вы можете использовать это:

 struct Workout_builder: View {
    @State var workouts = [  // <--- here
        Workout(name: "Bench Press", isActive: false),
        Workout(name: "Shoulder Press", isActive: false),
        Workout(name: "Incline Press", isActive: false),
        Workout(name: "Lateral Raises", isActive: false),
        Workout(name: "Tricep Cable", isActive: false),]
    
    var body: some View {
        VStack {
            List {
                ForEach($workouts)  { $workout in   // <--- here
                    Button(action: {
                        workout.isActive.toggle()
                    })
                    {
                        Text(workout.name)
                            .foregroundColor(.black)
                            .background(workout.isActive ? Color(.white) : Color(.blue))
                    }
                }
            }
        }
    }
}
 

Ответ №2:

Вам нужно использовать индекс для таких вещей, затем вы можете использовать для SwiftUI 1.0, 2.0 или 3.0, также вам нужна оболочка состояния для массива:

 struct Workout: Identifiable {
    var id = UUID()
    var name: String
    var isActive: Bool
    
}

struct ContentView: View {
    
    @State private var workouts = [Workout(name: "Bench Press", isActive: false),
                                   Workout(name: "Shoulder Press", isActive: false),
                                   Workout(name: "Incline Press", isActive: false),
                                   Workout(name: "Lateral Raises", isActive: false),
                                   Workout(name: "Tricep Cable", isActive: false)]
    
    var body: some View {
        
        VStack {
            
            List {
                
                ForEach(workouts.indices, id: .self)  { index in
                    Button(action: { workouts[index].isActive.toggle() })
                    {
                        Text( workouts[index].name)
                            .foregroundColor(.black)
                            .background(workouts[index].isActive ? Color(.white) : Color(.blue))
                    }
                }
            }
        }
    }
    
}
 

Ответ №3:

Я новичок в SwiftUI, но попробуйте следующее.

 import SwiftUI

struct Workout: Identifiable {
    var id = UUID()
    var name: String
    var isActive: Bool
}

var workouts = [
    Workout(name: "Bench Press", isActive: false),
    Workout(name: "Shoulder Press", isActive: false),
    Workout(name: "Incline Press", isActive: false),
    Workout(name: "Lateral Raises", isActive: false),
    Workout(name: "Tricep Cable", isActive: false),]

struct ContentView: View {
    var body: some View {
        VStack {
            List {
                ForEach(workouts)  { workout in
                    ForEach(workouts, id: .name) { workout in
                        CollectionView(workOut: workout)
                    }
                }
            }
        }
    }
}

struct CollectionView: View {
    @State var workOut: Workout
    var body: some View {
        Button(action: {
            workOut.isActive.toggle()
        }, label: {
            Text("(workOut.name)")
                .foregroundColor(.black)
                .background(workOut.isActive ? Color(.white) : Color(.blue))
        })
    }
}