繁体   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