【问题标题】:How to modify a variable that pass to an active sheet in swiftui如何在swiftui中修改传递给活动工作表的变量
【发布时间】:2021-05-20 08:43:14
【问题描述】:

我的 UIView 需要有一个对象传递给它,然后它才能显示为活动工作表。传入其中的对象取决于用户单击的按钮。这就是为什么我写了一些这样的代码。

struct DetailInfoView: View {
    
    var cat: Cat

@EnvironmentObject var modelData: ModelData
@State var activeSheet: DetailViewActiveSheet?

@State var selectedFood: Food?

var body: some View {
   ZStack {
   ForEach(foods, id:\.self) {food in
                                    Button(action: {
                                        selectedFood = food
                                        activeSheet = .foodDetailView
                                    }, label: {
                                        Text(food.name).font(.caption2).padding(.top, -5.0)                                             
                                        })
                                    }
    }
    }.sheet(item: $activeSheet) { item in
        switch item {
        case .foodDetailView:
            FoodDetailView(food: self.selectedFood!)
        }
    }
}

然后我发现即使我在按钮操作中设置了 selectedFood ,它也永远为零并导致异常。为什么会这样?

FoodDetailView 没有什么特别之处。

struct FoodDetailView: View {

 var food: Food

  var body: some View {
     Text(food.name)
  }
}

我有另一个视图将显示我所有的 FoodDetailView。每当我将 var food 更改为 FoodDetailView 的 @binding var food 时,它都会抱怨。

TabView() {
        ForEach(modelData.foods) { food in
            FoodDetailView(food: food)
        }
    }.tabViewStyle(PageTabViewStyle())

也许是为了澄清我的问题——应该是:

  1. 我有多个活动工作表。这就是为什么 .sheet 将接收项目 $activeSheet 以便我知道应该显示哪个其他视图。
  2. 对于要显示的每个视图,它们可能需要自定义项。只有当用户单击按钮时才能创建项目。但是,似乎在创建视图时创建了 .sheet 和相关代码,因此导致了异常。有建议告诉我应该在这里使用@binding。
  3. 如果我对变量 selectedFood 使用@binding,那么如果我在其他视图中没有任何绑定食物变量,我可以知道如何创建 FoodDetailView() 吗?例如,我有一个食品列表,我使用 for 循环只是循环并创建 FoodDetailView。在这种情况下,当我循环 Food Item 列表时,它不是绑定变量。

所以我认为我的问题是 --- 如何使在 .sheet() 中创建的那些 View 可以即时创建?

【问题讨论】:

  • 您的item 应该是self.selectedFood,即。模型,而不是视图。
  • 能分享一下DetailViewActiveSheet的模特吗?
  • 枚举 DetailViewActiveSheet: Identifiable { case FoodView case AudioView var id:Int { hashValue } }

标签: swift swiftui


【解决方案1】:

你能分享你的观点:FoodDetailView 吗? FoodDetailView(food: self.selectedFood!) 在出现 DetailInfoView 时启动。

我认为你可以这样编辑:

struct DetailInfoView: View {

var cat: Cat

@EnvironmentObject var modelData: ModelData
@State var activeSheet: DetailViewActiveSheet?

@State var selectedFood: Food = Food() //just init even as empty

var body: some View {
   ZStack {
    ForEach(foods, id:\.self) {food in
       Button(action: {
          selectedFood = food
          activeSheet = .foodDetailView
       }, label: {                   
          Text(food.name).font(.caption2).padding(.top, -5.0)                                             
       })
       }
    }
}.sheet(item: $activeSheet) { item in
    switch item {
    case .foodDetailView:
        FoodDetailView(food: self.selectedFood)
    }
}
}

并删除我之前在 FoodDetailView 中放置的 @Binding

【讨论】:

  • FoodDetailView 没有什么特别之处。更新。绑定传递是什么意思?该怎么做?
  • 它不起作用。这是因为我的代码的其他部分只会创建一个食物对象并加载 FoodDetailView。隐瞒绑定会导致其他部分失败:(实际上,我对“绑定”变量感到困惑。
  • 我可以在用户单击按钮时即时创建 FoodDetailView,而不是像您说的那样,当出现 DetailInfoView 时?
  • 你为什么使用 selectedFood 作为 Optional ?这就是导致您的异常的原因。
  • 您正在告诉您的观点 selectedFood 与 !当它不是。 :)
【解决方案2】:

item 是转移到 sheet 块中的内容,因此您的设计应与

}.sheet(item: $selectedFood) { item in
    switch item {
    case .foodDetailView:
        FoodDetailView(food: item)
    }
}

在这种情况下,item 在设置后包含selectedFood

【讨论】:

  • 我会有多个sheet,需要用item来切换。
  • 那么你用关联值枚举大小写,item 应该只有一个。
  • 是的,这就是我列举活动表的原因,而不是“食物”
  • 不,我的意思是你的项目应该是case .foodDetailView(let food),即。具有关联模型的枚举...在这种情况下,两种状态将不起作用 - 您必须选择单个项目。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-16
  • 2014-12-12
  • 2012-01-09
相关资源
最近更新 更多