【问题标题】:SwiftUI Sheet not updating variableSwiftUI 工作表不更新变量
【发布时间】:2020-05-14 08:44:28
【问题描述】:

如果我通过选择另一个项目来更改值,我正在尝试将一个项目传递给工作表。工作表一直显示第一项,即使我从未使用第一项调用工作表。

这是一个错误还是我做错了什么?

锻炼列表.swift

import SwiftUI

struct WorkoutList: View {
    private var workouts = workoutData
    @State var showWorkoutDetails = false

    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 20) {
                ForEach(workouts) { workoutCard in
                    GeometryReader { geometry in
                        Button(action: {self.showWorkoutDetails.toggle()}) {
                            WorkoutCardView(workout: workoutCard)
                                .rotation3DEffect(Angle(degrees: Double((geometry.frame(in: .global).minX - 30) / -30)), axis: (x: 0, y: 10, z: 0))
                                .sheet(isPresented: self.$showWorkoutDetails) {
                                    WorkoutDetails(workout: workoutCard)
                                }
                        }
                    }
                    .frame(width:246, height: 360)

                }
            }
        .padding(30)
        }
    }
}

private let workoutData = [
    Workout(name: "Workout #1", imageName: "workoutImage", color: Color.orange),
    Workout(name: "Workout #2", imageName: "workoutImage", color: Color.green),
    Workout(name: "Workout #3", imageName: "workoutImage", color: Color.red),
    Workout(name: "Workout #4", imageName: "workoutImage", color: Color.blue)
]

WorkoutDetails.swift

import SwiftUI

struct WorkoutDetails: View {
    var workout = Workout(name: "", imageName: "", color: Color.black)

    var body: some View {
        GeometryReader { geometry in
            ZStack {
                Rectangle()
                    .fill(self.workout.color)

                VStack(alignment: .leading) {
                    VStack(alignment: .leading) {
                        Text(self.workout.name)
                            .foregroundColor(.white)
                            .font(.title)
                            .fontWeight(.heavy)
                            .lineLimit(nil)
                            .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
                            .frame(height: 70)
                    }
                    .frame(width: 180)

                    Image(self.workout.imageName)
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .frame(width: geometry.size.width-60, height: 200)
                        .padding()

                    Spacer()
                }
                .padding(.top, 40)
                .padding(.leading, 10)
            }
        }
        .edgesIgnoringSafeArea(.bottom)
    }
}

我想在这里显示锻炼。但无论我改变它,我总是得到“锻炼#1”,我不知道我做错了什么。

【问题讨论】:

    标签: swift swiftui


    【解决方案1】:

    使用可选锻炼创建绑定。 Nil 将是不显示工作表的情况,将锻炼分配给此变量会显示相应的工作表。

    struct WorkoutList: View {
      private var workouts = workoutData
      @State var selectedWorkout: Workout?
    
      var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
          HStack(spacing: 20) {
            ForEach(workouts) { workoutCard in
              GeometryReader { geometry in
                Button(action: { self.selectedWorkout = workoutCard }) {
                  WorkoutCardView(workout: workoutCard).rotation3DEffect(Angle(degrees: Double((geometry.frame(in: .global).minX - 30) / -30)), axis: (x: 0, y: 10, z: 0)).sheet(item: self.$selectedWorkout) { workout in
                    WorkoutDetails(workout: workout)
                  }
                }
              }.frame(width:246, height: 360) 
            }
          }.padding(30)
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      我有类似的问题。您想将锻炼卡分配给 @State 和内部 .sheet 有一些逻辑来决定要显示什么视图

      这里有更多关于你的问题:Multiple sheet(isPresented:) doesn't work in SwiftUI

      【讨论】:

        【解决方案3】:

        基本上我们需要在点击按钮时存储selectedWorkout

        @State var isDetailPresented = false
        @State var selectedWorkout: Workout?
        
        ...
        
        Button(action: {
            self.selectedWorkout = workoutCard
            self.isDetailPresented.toggle()
        }, label: {
            //Your view here
        }).buttonStyle(PlainButtonStyle())
          .sheet(isPresented: $isDetailPresented) {
            WorkoutDetails(workout: self.selectedWorkout!)
        }
        ...
        

        【讨论】:

          【解决方案4】:
          1. 传递绑定而不是 @State 变量的值
          2. 在工作表中包含的视图主体中使用 Binding 的值
          struct WorkoutList: View {
              @State var isDetailPresented = false
              @State var selectedWorkout: Workout?
          
              var body: some View {
                  Button(action: {
                      self.selectedWorkout = workouts[yourIndex]
                      self.showWorkoutDetails.toggle()
                  }) {
                      Text("Test")
                  }
                  .sheet(isPresented: self.$showWorkoutDetails) {
                      WorkoutDetails(workout: selectedWorkout)
                  }
              }
          }
          struct WorkoutDetails: View {
              @Binding var workout: Workout?
          
              var body: some View {
                  ZStack {
                      Rectangle()
                          .fill(self.workout.color)
                      // your code
                  }
              }
          }
          

          【讨论】:

            【解决方案5】:

            我认为这里解释得更好 SwiftUI sheet doesn't access the latest value of state variables on first appearance

            struct DemoView: View {
              @State var showDetails: Bool = false
              var body: some View {
                VStack {
                    Button(action: {
                      showDetails = true
                    }) {
                        Text("Show sheet")
                    }
                }.sheet(isPresented: $showDetails){
                    SheetDetailView(flag: $showDetails)
                }
              }
            }
            
            struct SheetDetailView: View {
              @Binding var flag: Bool
                 var body: some View {
                   VStack {
                      Text("showDetails: \(flag ? "yes" : "no")")
                       }
                 }
            }
            

            只需在表单视图绑定中制作参数,并发送绑定参数,您仍然可以保留布尔切换。

            【讨论】:

              猜你喜欢
              • 2021-08-06
              • 2020-02-24
              • 2021-09-07
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-12-19
              • 2020-10-18
              • 1970-01-01
              相关资源
              最近更新 更多