English 中文(简体)
SwiftUI ForEEach协议的结果是 " 要求内容符合无障碍路标 "
原标题:SwiftUI ForEach of protocols results in "requirement that Content conform to AccessibilityRotorContent "
I m looking at iterating over an array of protocols and get them each to render a view. The protocol has a buildView function that returns any View, but calling this inside my view has the error: Static method buildExpression requires that Content conform to AccessibilityRotorContent Here s the code below, I don t really know what s going on and would greatly appreciate some help in debugging it. import UIKit import SwiftUI import PlaygroundSupport protocol ViewItem: AnyObject, Hashable, Identifiable { var id: UUID { get } func buildView() -> any View } class ViewOne: ViewItem { let id: UUID = UUID() func buildView() -> any View { Text("View one") } static func == (lhs: ViewOne, rhs: ViewOne) -> Bool { lhs.id == rhs.id } func hash(into hasher: inout Hasher) { hasher.combine(id) } } class ViewTwo: ViewItem { let id: UUID = UUID() func buildView() -> any View { Text("View two") } static func == (lhs: ViewTwo, rhs: ViewTwo) -> Bool { lhs.id == rhs.id } func hash(into hasher: inout Hasher) { hasher.combine(id) } } struct ContentView: View { let viewItems: [any ViewItem] var body: some View { VStack { ForEach(viewItems, id: .id) { viewItem in viewItem.buildView() <------------------ ERROR HERE } } } }
问题回答
func buildView() -> any View The code above is not allowed within body, with or without ForEach. var body: some View { VStack { createAnyView() // ❌ createSomeView() // ✅ } } func createAnyView() -> any View { Text("any view") } func createSomeView() -> some View { Text("some view") } AFAIK, the body must contain some View or a type-erased AnyView. So, an approach is changing your protocol function to: protocol ViewItem { ... func buildView() -> AnyView } class ViewOne: ViewItem { func buildView() -> AnyView { AnyView( Text("View one") ) } } However, it has drawbacks such as unpredictable view state, animation, performance, etc... since SwiftUI doesn t even know what View it will be to optimize when it needs to re-render. You can check this out Demystify SwiftUI performance. Thus, if I were you, I would go with some View solution: protocol ViewItem { ... associatedtype ContentView: View func buildView() -> ContentView } Then I will wrap each type into a kind of builder, because passing directly ViewItem into a View will force the input param to any as mentioned in SE-0335. enum Content: View, Identifiable { case viewOne(ViewOne) case viewTwo(ViewTwo) var body: some View { switch self { case .viewOne(let viewOne): viewOne.buildView() case .viewTwo(let viewTwo): viewTwo.buildView() } } var id: ObjectIdentifier { switch self { case .viewOne(let viewOne): return viewOne.id case .viewTwo(let viewTwo): return viewTwo.id } } } Finally, implement ContentView as normal: struct ContentView: View { var items: [Content] var body: some View { VStack { ForEach(items) { item in item.body } } } } #Preview { ContentView(items: [ .viewOne(.init()), .viewTwo(.init()) ]) } Side note: If you have several return statements in each ViewItem, you might consider adding @ViewBuilder to your protocol to use the power of function builder.




相关问题
SwiftUI: How do I position a button x points above a sheet?

I am trying to recreate a Maps-style UI with a persistent bottom sheet and controls fixed above. Apple Maps UI with controls above ☝️ Example here, the "Look Around" binoculars button and ...

BraintreeDropIn deprecated functions error

I m getting this error on the latest release of BraintreeDropIn, I really don t get it since based on the patch notes, this should ve been addressed already, I have already tried cleaning derived data,...

how to limit zoom level in map swift ui?

how to limit zoom level in map swift ui i have map and need to make zoom level limited Map(coordinateRegion: $region,annotationItems: viewModel.nearbyGyms) { item in ...

UIImageView - How to get the file name of the image assigned?

Is it possible to read the name of an UIImageView s UIImage that s presently stored in the UIImageView? I was hoping you could do something kind of like this, but haven t figured it out. NSString *...

热门标签