3

在 SwiftUI 中,您可以将多个视图作为一个参数传递给另一个视图,这要归功于@ViewBuilder. 每个子视图都被单独处理,因此在被传递后,可以包含在 aVStack等中HStack

我的问题是:这个容器视图是否可以单独修改传递给它的每个子视图?例如,通过Spacer在每个子视图之间添加一个。

这是我正在寻找的等效功能:

struct SomeContainerView<Content: View> {
    
    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content()
    }
    
    let content: Content
    
    var body: some View {
        HStack {
            ForEach(content.childViews, id: \.id) { child in
                // Give each child view a background
                // Add a Spacer in between each child view
                // Conditional formatting
                // Etc.
            }
        }
    }
    
}

我相信这是可能的,因为标准 SwiftUI 容器视图会影响传递给它们的子视图的外观和布局。除非这是通过 SwiftUI 的内部功能实现的?

解决此问题的一种方法可能是传递多个视图参数而不是一个,但如果需要传递许多视图,这是不灵活且混乱的。视图数组似乎也没有意义,因为我在 SwiftUI 的任何地方都没有注意到这种模式。

4

3 回答 3

1

根据我与@ViewBuilder 合作的个人经验,这是不可能的,例如,当您将按钮和文本以及可能的 HStack 传递给 SomeContainerView 时,它将所有这些都作为单个视图(如 VStack 或您命名的任何内容)。并且任何修改都会发生在整个视图上,但是当您将 ForEach 传递给您的 SomeContainerView 时,事情会有所不同,在这种情况下,您在发送 SomeContainerView 之前或多或少具有相同级别的控制,并且您可以根据需要修改每一行但是它是有限的控制,例如,您无法再访问索引或项目,而您可以在 ForEach 中拥有它。让我给你更多的光看事物,即使你在正文中工作我的意思是在正文中单行运行代码之后观察和控制视图的更高级别它不再是可编辑的,例如你有一个文本,你给这个文本一个背景颜色,过了一段时间你想摆脱那个颜色,所以在给那个 bachgroundColor 之后,SwiftUI 不再有控制权,那么它必须重新- 渲染/重新构建没有背景颜色的文本来回答您的订单,这是 SwiftUI 和 UIKit-Swift 之间的最大区别,视图就像火灾后的子弹,您无法捕捉或编辑它,您必须发射一个新的子弹到你想要的目标,所以再次回到你的问题,在你发送一个或一些视图到你的 SomeContainerView 之后,它几乎把它当作一个单一的视图。

但是如果你真的很想实现你想要的事情,那么你应该尝试其他的东西,比如 AnyView 数组可以解决你的问题,但你必须密切关注管理和控制该数组。

于 2021-02-22T11:56:03.293 回答
1

据我所知,你不能做这样的事情。但是您可以使用数组 View 并迭代视图并修改您的子视图。

这是演示:

struct SomeModel<Content: View>: Identifiable {
    var body: Content
    var id = UUID()
}

public struct SomeContainerView<Content: View>: View {
    
    let items: [SomeModel<Content>]
    
    init(items: [SomeModel<Content>]) {
        self.items = items
    }
    
    public var body: some View {
        HStack {
            ForEach(items.indices) { index in
                items[index].body.background(index % 2 == 0 ? Color.red : Color.green)
            }
        }
    }
}

struct TestSomeView: View {
    
    var body: some View {
        SomeContainerView(items: [.init(body: Text("Child_view_1")),
                           .init(body: Text("Child_view_2")),
                           .init(body: Text("Child_view_3"))])
    }
}

在此处输入图像描述

于 2021-02-22T12:07:09.670 回答
0

一个更好的主意是让调用者决定如何在视图中布局内容,模型决定每个输入的数据。检查下面的代码:

import SwiftUI

struct SomeContainerView<Content: View>:View {
    
    var model:[Model] = []
    
    init(model:[Model],@ViewBuilder content: @escaping (Model) -> Content) {
        self.content = content
        self.model = model
    }
    
    let content: (Model) -> Content
    
    var body: some View {
        
        VStack{
            ForEach(model,id:\.id, content: content)
            Spacer()
        }
    }
}

struct MainView:View {
    @ObservedObject var modelData:objects
    
    var body: some View{
        SomeContainerView(model: modelData.myObj){ data in
            Text(data.name)
                .background(data.color)
            
        }
    }
}

struct Model{
    
    var id = UUID().uuidString
    var name:String
    var color:Color
    
    init(name:String,color:Color) {
        self.name = name
        self.color = color
    }
    
}

class objects:ObservableObject,Identifiable{
    
    var id = UUID().uuidString
    @Published var myObj:[Model] = []
    
    init() {
        initModel()
    }
    
    func initModel(){
        let model = Model(name: "Jack", color: .green)
        let model1 = Model(name: "hey Jack", color: .red)
        
        myObj.append(model)
        myObj.append(model1)
    }
    
}

@主要的 -:

import SwiftUI

    @main
    struct WaveViewApp: App {
        
        @StateObject var dataObj : objects
        
        init() {
            let obj = objects()
           _dataObj = StateObject(wrappedValue: obj)
            
        }
        var body: some Scene {
            WindowGroup {
                MainView(modelData: dataObj)
            }
        }
    }

输出-:

在此处输入图像描述

于 2021-02-22T12:48:02.593 回答