簡體   English   中英

類型任何協議不能符合協議

[英]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的類型,則另一種解決方法是使用原始解決方案但不使用符合HashableElement

struct InternalView<Element, Content: View>: View {
    private let items: [Element]
    private let content: (Int, Element) -> Content

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM