ios - 如何在 SwiftUI View 中显示协议(protocol) View ?

标签 ios swift swiftui

我有一个这样的对象协议(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是一个通用的关联类型。

我们需要保留完整的通用类型信息,以满足 Viewbodysome 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/

相关文章:

swift - 列表中的 Int 和 String 是 AnyObject 吗?

swift - 为什么我不能在 swift 中的 for 循环中观看多个文件?

swiftui - 在 macOS 上的 SwiftUI 中将颜色从源拖放到目标

ios - SwiftUI - 如何避免在修改来自同一结构的状态变量时刷新列表

ios - NSRange 永远不能为零,不允许比较 Swift

ios - 在 iOS Swift 中使用 Alamofire 发送带有 MultipartFormData 的 POST 参数

ios - 使用联系人框架获取本地化电话标签

ios - 使用 NSUserDefaults 在 SWIFT 中添加 24 小时倒计时器

ios - 以编程方式添加的按钮在 ios 中不显示触摸感

ios - 如何在SwiftUI中更改NavigationView目标?