我有一个从ForEach循环生成的列表:
struct TrainingList: View {
@EnvironmentObject var trainingVM: TrainingViewModel
var body: some View {
VStack(alignment: .leading) {
Text("Your training sessions")
.font(.system(size: 35, weight: .semibold, design: .default))
.padding(.all, 10)
.foregroundColor(.white)
Divider()
ScrollView{
if(trainingVM.loading){
ProgressView("Loading training session").progressViewStyle(CircularProgressViewStyle(tint: .blue))
}
LazyVStack {
ForEach(trainingVM.trainingList) { training in
TrainingCell(training: training)
}
}
}
Spacer()
}
.background {
Rectangle()
.fill(Color(.sRGB, red: 41/255, green: 41/255, blue: 41/255))
.cornerRadius(10, corners: [.topRight, .bottomRight])
.shadow(color: .black.opacity(1), radius: 8, x: 6, y: 0)
}
.frame(width: 650)
.zIndex(.infinity)
}
}
每个TrainingCell都有一个按钮,可在其侧面打开一个额外的面板。为了指示面板打开了哪一行,按钮将更改其样式:
struct TrainingCell: View {
@EnvironmentObject var trainingVM: TrainingViewModel
@State var showEvents = false
let training: Training
var body: some View {
HStack(spacing: 0) {
ZStack(alignment: .top) {
RoundedRectangle(cornerRadius: 10, style: .continuous)
.fill(Color(.sRGB, red: 41/255, green: 41/255, blue: 41/255))
VStack {
HStack(spacing: 10) {
VStack(alignment: .leading, spacing: 5) {
HStack{
Text(training.readableDate, style: .date)
.font(.system(size: 25, weight: .semibold, design: .default))
.foregroundColor(.white)
Text(" | ")
Text(training.readableDate, style: .time)
.font(.system(size: 25, weight: .semibold, design: .default))
.foregroundColor(.white)
}
VStack(alignment: .leading,spacing: 5){
HStack {
HStack(spacing: 5) {
Image(systemName: "person.text.rectangle.fill")
.foregroundColor(Color(.sRGB, red: 10/255, green: 90/255, blue: 254/255))
Text(training.instructor.fullName)
.foregroundColor(.white)
}
}
HStack{
ForEach(training.students){ student in
HStack(spacing: 5) {
Image(systemName: "person")
.imageScale(.medium)
.foregroundColor(Color(.sRGB, red: 10/255, green: 90/255, blue: 254/255))
Text(student.fullName_shortenedFirstName)
.foregroundColor(.white)
}
}
}
}
.font(.system(size: 20, weight: .regular, design: .default))
.foregroundColor(.primary)
}
.frame(maxHeight: .infinity, alignment: .center)
.clipped()
Spacer()
View_Close_Button(showEvents: $showEvents)
}
.frame(maxWidth: .infinity, maxHeight: 80, alignment: .top)
.padding(.all)
.background {
RoundedRectangle(cornerRadius: 0, style: .continuous)
.fill(Color(.sRGB, red: 41/255, green: 44/255, blue: 49/255))
.shadow(color: .black.opacity(1), radius: 5, x: 0, y: 5)
}
}
}
}
}
}
按钮代码:
struct View_Close_Button: View {
@EnvironmentObject var trainingVM: TrainingViewModel
@Binding var showEvents: Bool
var body: some View {
HStack
{
Image(systemName: showEvents ? "xmark" : "eye")
.imageScale(.large)
.padding(.horizontal, 5)
.font(.system(size: 17, weight: .regular, design: .default))
Text(showEvents ? "Close" : "View")
.padding(.all, 10)
.font(.system(size: 25, weight: .regular, design: .default))
.multilineTextAlignment(.leading)
}
.onTapGesture {
withAnimation(.easeIn(duration: 0.3)) {
showEvents.toggle()
if(showEvents) {
trainingVM.showingEvents = true
}else{
trainingVM.showingEvents = false
}
}
}
.foregroundColor(.white)
.background {
Capsule(style: .continuous)
.foregroundColor(showEvents ? Color(.sRGB, red: 253/255, green: 77/255, blue: 77/255) : Color(.sRGB, red: 10/255, green: 90/255, blue: 254/255))
.clipped()
.frame(maxWidth: 180)
}
}
}
结果应该是:
我唯一的问题是所有的按钮都可以同时激活。当一个按钮被点击时,我如何去禁用其余的按钮呢?
我需要用户只能将其中一个按钮显示为“X关闭”
我想过在激活一个被点击的按钮之前,通过其他按钮的循环来取消激活它们,但我不知道如何去做
1条答案
按热度按时间eufgjt7s1#
您可以在父视图中跟踪激活的按钮。
如果每个按钮都有某种唯一标识符,则可以在包含活动标识符的父视图中创建一个变量。
您可以将该变量作为绑定传递到按钮视图中,并根据该绑定更改视图外观。
这样,始终只有一个活动按钮。当单击按钮时,您可以使用该按钮的唯一标识符设置按钮视图中绑定变量的值,其他视图将自动更改。
在TrainingList上,您可以使用活动选项卡定义变量:
在TrainingCell上,您可以将此变量添加为绑定。
然后你就这样传过去:
然后,在View_Close_Button上,您可以添加两个变量:
并在TrainingCell上这样传递它:
在View_Close_Button中,您可以使用此选项获取值并相应地设置样式:
您可以设置它何时按下按钮: