[英]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.