Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SwiftUI将@EnvironmentObject与选择器一起使用会导致ScrollView contentOffset绑定警告_Swiftui - Fatal编程技术网

SwiftUI将@EnvironmentObject与选择器一起使用会导致ScrollView contentOffset绑定警告

SwiftUI将@EnvironmentObject与选择器一起使用会导致ScrollView contentOffset绑定警告,swiftui,Swiftui,我有一个watchOS应用程序,它有两个屏幕。当我导航到第二个屏幕时,控制台中会出现以下警告: ScrollView contentOffset绑定已被读取;这将导致非常低效的视图性能,因为每当其contentOffset更改时,ScrollView的内容都会更新。在绑定创建者和ScrollView之间未设置父级的视图中读取contentOffset绑定,以避免出现这种情况 这似乎与在第二个屏幕中使用@EnvironmentObject进行选择器选择有关。如果删除@EnvironmentObje

我有一个watchOS应用程序,它有两个屏幕。当我导航到第二个屏幕时,控制台中会出现以下警告:

ScrollView contentOffset绑定已被读取;这将导致非常低效的视图性能,因为每当其contentOffset更改时,ScrollView的内容都会更新。在绑定创建者和ScrollView之间未设置父级的视图中读取contentOffset绑定,以避免出现这种情况

这似乎与在第二个屏幕中使用@EnvironmentObject进行选择器选择有关。如果删除@EnvironmentObject并将其替换为选择器选择的@State,则不会出现警告。(但更新不会反映在第一个屏幕上)

为什么会这样?我能做些什么来阻止这个警告

这是我的密码:

第一屏:

import SwiftUI

struct ContentView: View {
  @EnvironmentObject var itemManager: ItemManager

  var body: some View {
    List {
      ForEach(itemManager.items.indices) { index in
        NavigationLink(destination: ItemView(index: index)) {
          VStack(alignment: HorizontalAlignment.leading) {
            HStack {
              Text(self.itemManager.items[index].name)
              Spacer()
              Text("x")
              Text(String(self.itemManager.items[index].quantity))
            }
            Text(self.itemManager.items[index].type.rawValue).font(.footnote)
          }
        }
      }
    }
  }
}

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView().environmentObject(ItemManager())
  }
}
第二屏:

import SwiftUI

struct ItemView: View {

  @EnvironmentObject var itemManager: ItemManager
  var index: Int

  var body: some View {

    VStack {
      Text("Update")
      Form {
        Section {
          Picker(selection: $itemManager.items[index].type, label: Text("Food Type")) {
            ForEach(FoodType.allCases.sorted()) { type in
              Text(type.rawValue).tag(type)
            }
          }
        }
      }
    }.navigationBarTitle(Text("Item"))
  }
}

struct ItemView_Previews: PreviewProvider {
  static var previews: some View {

    return ItemView(index: 0).environmentObject(ItemManager())
  }
}

型号:

import Foundation

enum FoodType: String, CaseIterable, Identifiable, Comparable{
  case fruit
  case vegetable
  case poultry
  case bakery
  var id: FoodType{self}

  static func < (lhs: FoodType, rhs: FoodType) -> Bool {
    lhs.rawValue < rhs.rawValue
  }
}

struct Item {
  var type: FoodType
  var quantity: Int
  var name: String
}

class ItemManager: ObservableObject {

  @Published var items: [Item] =
    [
      Item(type: FoodType.fruit, quantity: 1, name: "apple"),
      Item(type: FoodType.bakery, quantity: 1, name: "french bread"),
      Item(type: FoodType.vegetable, quantity: 6, name: "carrots")
  ]
}

<代码>导入基础 枚举FoodType:字符串、可大小写、可识别、可比较{ 果壳 果蔬 案例家禽 凯斯面包店 变量id:FoodType{self} 静态函数<(左:FoodType,右:FoodType)->Bool{ lhs.rawValue 主机控制器:

import WatchKit
import Foundation
import SwiftUI

class HostingController: WKHostingController<AnyView> {
    override var body: AnyView {
      return AnyView(ContentView()
      .environmentObject(ItemManager()))
    }
}

导入WatchKit
进口基金会
导入快捷键
类HostingController:WKHostingController{
覆盖变量主体:AnyView{
返回AnyView(ContentView())
.environmentObject(ItemManager())
}
}

最后,我在第二个屏幕(ItemView)上使用@State it,并在视图消失时设置@EnvironmentObject itemManager

第一屏:

import SwiftUI

struct ContentView: View {
  @EnvironmentObject var itemManager: ItemManager

  var body: some View {
    List {
      ForEach(itemManager.items, id: \.self) { item in
        NavigationLink(destination: ItemView(selection: item.type, food: item)) {
          VStack(alignment: HorizontalAlignment.leading) {
            HStack {
              Text(item.name)
              Spacer()
              Text("x")
              Text(String(item.quantity))
            }
            Text(item.type.rawValue).font(.footnote)
          }
        }
      }
    }
  }
}

struct ContentView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView().environmentObject(ItemManager())
  }
}
注:

第二屏:

import SwiftUI

struct ItemView: View {

  @EnvironmentObject var itemManager: ItemManager
  @State var selection : FoodType
  var food: Item
  var itemIndex: Int { 
    itemManager.items.firstIndex(where: { $0.id == food.id })!
  }

  var body: some View {

    VStack {
      Text("Update")
      Form {
        Section {
          Picker(selection: $selection, label: Text("Food Type")) {
            ForEach(FoodType.allCases.sorted()) { type in
              Text(type.rawValue).tag(type)
            }
          }
        }
      }
    }.navigationBarTitle(Text("Item"))
    .onDisappear {
      self.itemManager.items[self.itemIndex].type = self.selection
    }
  }
}

struct ItemView_Previews: PreviewProvider {
  static var previews: some View {
    let food = Item(id: UUID(), type: FoodType.fruit, quantity: 1, name: "apple")
    return ItemView(selection: FoodType.fruit, food: food)
  }
}