我正在try 编写一个协议,要求符合者具有视图属性,或返回一些视图的@ViewBuilder方法.

我希望有一个可重用的复合视图,可以根据需要显示的数据类型构建不同的子视图.

协议看起来像这样…

protocol RowView {
    var leftSide: some View { get }
    var rightSide: some View { get }
}

这样我可以称之为这样的事情…

struct Example: RowView {
    var id: Int
    var leftSide: some View { … }
    var rightSide: some View { … }
}

struct ContentView: View {
    let rows: [RowView]

    var body: some View {
        VStack {
            Foreach(rows, id: \.id) {
                HStack {
                    $0.leftSide
                    $0.rightSide
                }
            }
        }
    }
}

推荐答案

您需要将协议更改为:

protocol RowView {
    associatedtype LView: View
    associatedtype RView: View

    var leftSide: LView { get }
    var rightSide: RView { get }
}

此外,在内容视图中使用具体的Example类型,而不是协议(您定义的协议根本没有id):

let rows: [Example]

而且你可以根据需要将RowView变成identifiable,因此不再需要id: \.id:

protocol RowView: Identifiable

工作代码:

protocol RowView: Identifiable {
    associatedtype LView: View
    associatedtype RView: View

    var leftSide: LView { get }
    var rightSide: RView { get }
}

struct Example: RowView {
    var id: Int
    var leftSide: some View { Text("Left") }
    var rightSide: some View { Text("Right") }
}

struct ContentView: View {
    let rows: [Example] = [
        .init(id: 1),
        .init(id: 2)
    ]

    var body: some View {
        VStack {
            ForEach(rows) { row in
                HStack {
                    row.leftSide
                    row.rightSide
                }
            }
        }
    }
}

Swift相关问答推荐

计算Vision OS相机与Vision OS中3D模型之间的距离

Swift concurrency reload/await,支持只执行成功并重试

为什么ClosedRange<;Int&>包含的速度比预期慢340万倍?

当计数大于索引时,索引超出范围崩溃

在Swift中,将秒设置为0也等于将1添加到分钟

在一行语句中比较Date.now的相等性是否安全

在SwiftUI中使用ForEach循环来显示字典项的键和值在Form视图中

VisionOS TabBar预览中是否存在漏洞?

在 SwiftUI 中禁用 Select 器选项

memcpy 复制带偏移量的数组

从 iPhone 中的安全飞地获取真正的随机数?

MacOS KIND 是如何实现的

自定义选取器的出现导致其他视图重新排列

如何让动画变慢 SwiftUI

更改该函数的参数之一时,如何将这些 SwiftUI 异步任务合并到一个任务中以从函数中获得正确的结果

如何将使用\u{ea12}创建的 Swift 字符串转换回其十六进制值/字符串ea12?

无法从自定义动态框架(Swift)访问类

如何删除桥头而不出错?

如何在 SwiftUI 中实现 PageView?

在 Swift 中将计时器标签格式化为小时:分钟:秒