我有一个watchOS应用,该应用有两个屏幕。当我导航到第二个屏幕时,在控制台中收到以下警告:
ScrollView contentOffset绑定已被读取;每当ScrollView的contentOffset更改时,其内容都会被更新,这将导致视图性能严重低下。避免在绑定的创建者和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")
]
}
HostingController:
import WatchKit
import Foundation
import SwiftUI
class HostingController: WKHostingController<AnyView> {
override var body: AnyView {
return AnyView(ContentView()
.environmentObject(ItemManager()))
}
}
答案 0 :(得分:0)
我最终在第二个屏幕(ItemView)中使用@State,并在视图消失时设置@EnvironmentObject itemManager。
第一个屏幕:
.btn-custom {
border: none;
outline: none;
}
注意: I got the var itemIndex: Int strategry from the Landmark apple tutorial
第二屏幕:
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())
}
}