[英]Type any Protocol cannot conform to Protocol
我在嘗試初始化 SwiftUI 中的視圖時遇到問題。讓我解釋一下:
我有一個名為 ExternalView 的視圖,該視圖具有一個名為 ToggleableProtocol 的協議的約束,然后,該視圖在內部使用一個名為 InternalView 的視圖,該視圖具有對 Hashable 協議的約束。
當我嘗試創建 ExternalView 的實例並將符合 ToggleableItem 協議的不同結構數組傳遞給它時,會發生錯誤。 錯誤提示Type 'any TogleableItem' cannot conform to 'TogleableItem'
可切換項目
public protocol TogleableItem: Hashable {
var text: String { get }
var isSelected: Bool { get set }
}
符合 TogleableItem 的結構
struct FirstObject: TogleableItem {
var text = "FirstItem"
var isSelected = false
}
struct SecondObject: TogleableItem {
var text = "SecondItem"
var isSelected = false
}
內容視圖
struct ContentView: View {
@State private var items: [any TogleableItem] = [
FirstObject(),
SecondObject()
]
var body: some View {
ExternalView(
items: items
) { isSelected, index, _ in
items[index].isSelected = isSelected
}
}
}
外部視圖
public struct ExternalView<T: TogleableItem>: View {
private let items: [T]
private let onItemTap: (Bool, Int, T) -> Void
public init(
items: [T],
onItemTap: @escaping (Bool, Int, T) -> Void
) {
self.items = items
self.onItemTap = onItemTap
}
public var body: some View {
InternalView(
items: items
) { index, element in
Text(element.text)
.foregroundColor(element.isSelected ? .red : .blue)
}
}
}
內部視圖
struct InternalView<Element: Hashable, Content: View>: View {
private let items: [Element]
private let content: (Int, Element) -> Content
init(
items: [Element],
content: @escaping (Int, Element) -> Content
) {
self.items = items
self.content = content
}
var body: some View {
LazyHStack(spacing: 0) {
ForEach(items.indices, id: \.self) { index in
content(index, items[index])
}
}
}
}
謝謝!!
我嘗試將 ExternalView 內的 items 參數更改為 [any TogleableItem] 之類的內容,但最終在使用 InternalView 時會導致類似的錯誤
您的代碼的問題是您將例如ExternalView
定義為通用
ExternalView<T: TogleableItem>
然后你說T
可以是符合TogleableItem
的(讀取一個)類型,但你想將視圖用於符合TogleableItem
的混合類型。
我看到的解決方案是不創建視圖類型 generics 而是直接在聲明中使用TogleableItem
(為簡潔起見,我在下面跳過了很多代碼)
public struct ExternalView: View {
private let items: [any TogleableItem]
private let onItemTap: (Bool, Int, any TogleableItem) -> Void
...
}
struct InternalView<Content: View>: View {
private let items: [any TogleableItem]
private let content: (Int, any TogleableItem) -> Content
...
}
如果 InternalView 應該能夠使用其他類型而不是符合TogleableItem
的類型,則另一種解決方法是使用原始解決方案但不使用符合Hashable
的Element
struct InternalView<Element, Content: View>: View {
private let items: [Element]
private let content: (Int, Element) -> Content
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.