我有一个这样的对象协议(protocol):
public protocol Viewable {
associatedtype Content: View
var parent: (any Viewable)? { get }
var body: Content { get }
}
我想要的是在另一个 View 中显示 View 的主体,如下所示:
public struct SampleView: View {
var object: (any Viewable)?
public var body: some View {
object!.body
}
}
但我收到错误类型“任何 View ”无法符合“ View ”
在不使用 AnyView 的情况下显示协议(protocol)扩展中定义的对象 View 的最佳方式是什么??
谢谢。
最佳答案
您的对象
不能是存在类型(动态类型协议(protocol)),因为View
的协议(protocol)要求指定View.Body
是一个通用的关联类型。
我们需要保留完整的通用类型信息,以满足 View
上 body
的 some View
要求。
答案是使用具体的泛型类型:
public struct SampleView: View {
var object: (some Viewable)?
public var body: some View {
object!.body
}
}
为了清楚起见,可以更传统地拼写它,以明确这是自定义协议(protocol)的一般约束类型:
public struct SampleView<T: Viewable>: View {
var object: T?
public var body: some View {
object!.body
}
}
此行为在 SE-0309 的提案中有更详细的说明。最初允许存在类型用于任何协议(protocol)类型。
要仍然以异构方式使用 Viewable
类型(例如在数组中),您需要创建一个额外的抽象层,例如使用具体的方法创建一个 enum
值作为关联值。
struct SampleView: Viewable { ... }
struct ProfileView: Viewable { ... }
struct PreferencesView: Viewable { ... }
enum Views {
case sample(SampleView)
case profile(ProfileView)
case preferences(PreferencesView)
}
var views = [Views]()
现在您可以访问关联值中的具体类型。
显然,此解决方案的扩展性较差,并且应在有限的情况下使用这种处理泛型类型的方法,以避免此枚举
在许多情况下变得非常大。
关于ios - 如何在 SwiftUI View 中显示协议(protocol) View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75667483/