自从今天早些时候更新到Xcode Beta 6以来,我的应用程序将不再构建,它在Beta 5及更早版本中运行良好。
这是带有错误消息的文件中的代码,尽管我现在知道这并不一定意味着这实际上是错误所在。
import SwiftUI struct JobView_Table : View { @ObservedObject var jobList: JobDetailViewModel = JobDetailViewModel() var body: some View { NavigationView { List { ForEach($jobList.jobDetails) { job in NavigationLink(destination: JobDetailHost(jobDetails: job)) { // ERROR: "Type of expression is ambiguous without more context" JobView_List(jobDetails: job) } } } .navigationBarTitle(Text("My Jobs")) .onAppear(perform: fetchData) .onAppear(perform: { print("Hello!") }) } } private func fetchData() { return(jobList.updateDetails()) } }
包含数据的结构正确符合以下协议。
struct JobDetails: Codable, Identifiable, Equatable, Hashable { ... ... }
这是向提供数据的类JobView_Table。
JobView_Table
import Foundation import UIKit import Combine class JobDetailViewModel: ObservableObject, Identifiable { @Published var jobDetails: [JobDetails] = [] func updateDetails() { self.jobDetails = DataManager().fetchJobList() } }
最后是通过链接到的目标视图NavigationLink。
NavigationLink
struct JobDetailHost: View { @Environment(\.editMode) var mode @Binding var jobDetails: JobDetails var body: some View { VStack { JobDetailView(jobDetails: jobDetails) } .navigationBarItems(trailing: EditButton()) } }
我注意到其他一些人似乎也有类似的问题,例如下面列出的两个问题,但是目前这些问题的答案仍然无济于事。
编辑:
我试过实施Fabian的建议,这已消除了错误,但是列表中没有内容。
这是调整后的List代码,可以成功编译,但是在运行应用程序时不会填充列表。
List
List { ForEach(jobList.jobDetails.indexed(), id: \.1.id) { (index, job) in NavigationLink(destination: JobDetailHost(jobDetails: self.$jobList.jobDetails[index])) { Text(job.jobName) } } }
以下代码不使用ForEach和丢弃NavigationLink,并且仍然无法正常工作。
ForEach
List(jobList.jobDetails.indexed(), id: \.1.id) { (index, job) in Text(job.jobName) }
我将引用macOS Catalina 10.15 Beta 6发行说明:
绑定结构对Collection协议的条件一致性已删除。(51624798) 如果您具有以下代码: struct LandmarkList: View { @Binding var landmark: [Landmark] var body: some View { List(landmarks) { landmark in Toggle(landmark.value.name, isOn: landmark[\.isFavorite]) } } } 定义以下收集类型: struct IndexedCollection<Base: RandomAccessCollection>: RandomAccessCollection { typealias Index = Base.Index typealias Element = (index: Index, element: Base.Element) let base: Base var startIndex: Index { base.startIndex } var endIndex: Index { base.endIndex } func index(after i: Index) -> Index { base.index(after: i) } func index(before i: Index) -> Index { base.index(before: i) } func index(_ i: Index, offsetBy distance: Int) -> Index { base.index(i, offsetBy: distance) } subscript(position: Index) -> Element { (index: position, element: base[position]) } } extension RandomAccessCollection { func indexed() -> IndexedCollection<Self> { IndexedCollection(base: self) } } 然后,将代码更新为: struct LandmarkList: View { @Binding var landmarks: [Landmark] var body: some View { // Does often give error on id: \.1.id List(landmarks.indexed(), id: \.1.id) { (index, landmark) in Toggle(landmark.name, isOn: self.$landmarks[index].isFavorite) } } }
绑定结构对Collection协议的条件一致性已删除。(51624798)
如果您具有以下代码:
struct LandmarkList: View { @Binding var landmark: [Landmark] var body: some View { List(landmarks) { landmark in Toggle(landmark.value.name, isOn: landmark[\.isFavorite]) } } }
定义以下收集类型:
struct IndexedCollection<Base: RandomAccessCollection>:
RandomAccessCollection { typealias Index = Base.Index typealias Element = (index: Index, element: Base.Element)
let base: Base var startIndex: Index { base.startIndex } var endIndex: Index { base.endIndex } func index(after i: Index) -> Index { base.index(after: i) } func index(before i: Index) -> Index { base.index(before: i) } func index(_ i: Index, offsetBy distance: Int) -> Index { base.index(i, offsetBy: distance) } subscript(position: Index) -> Element { (index: position, element: base[position]) } } extension RandomAccessCollection { func indexed() -> IndexedCollection<Self> { IndexedCollection(base: self) } }
然后,将代码更新为:
struct LandmarkList: View { @Binding var landmarks: [Landmark] var body: some View { // Does often give error on id: \.1.id List(landmarks.indexed(), id: \.1.id) { (index, landmark) in Toggle(landmark.name, isOn:
self.$landmarks[index].isFavorite) } } }
您的代码也带有Binding<[JobDetails]>with $jobList.jobDetails,但Binding<[JobDetails]>不再符合Collection协议。
Binding<[JobDetails]>
$jobList.jobDetails
但是请注意上面的解决方案,\.1.id由于编译器无法理解,我遇到了无法识别的情况,这\.1是指元组IndexedCollection定义中的第二个元素,但是我可能使用了错误的内容。可以重写它,但这使它起作用。
\.1.id
\.1
IndexedCollection
struct AnotherIndexedView_NeedsEnv: View { @EnvironmentObject var modalManager: ModalManager var body: some View { ZStack { SwiftUI.ForEach(modalManager.modals.indexed()) { m in ModalView(currentModal: self.$modalManager.modals[m.index]).environmentObject(self.modalManager) } }.onAppear(perform: {self.modalManager.fetchContent()}) } }