首页 > 解决方案 > SwiftUI 自定义视图接受带有 ID 的视图?

问题描述

我很可能忽略了一个简单的答案,但我似乎被困在如何做到这一点上。我尝试了很多东西,但我觉得有一个更简单的解决方案。

代码的示例...

struct CustomView<Content: View>: View {
    var content: Content
    
    init(content: @escaping () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        
        ZStack {
         
            GeometryReader { geometry in

                let quadrant = geometry.size.height * 0.5
                
                VStack(spacing: 0) {
                    
                    HStack(spacing: 0) {
                        
                         // content.id(1)
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                            .background(Color.blue)
                            .cornerRadius(20)
                            .padding(10)
                            .frame(width: quadrant, height: quadrant)
                        
                         // content.id(2)
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                            .background(Color.blue)
                            .cornerRadius(20)
                            .padding(10)
                            .frame(width: quadrant, height: quadrant)
                            
                    }
                    
                    
                    HStack(spacing: 0) {
                         // content.id(3)
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                            .background(Color.blue)
                            .cornerRadius(20)
                            .padding(10)
                            .frame(width: quadrant, height: quadrant)
                        
                        // content.id(4)
                            .frame(maxWidth: .infinity, maxHeight: .infinity)
                            .background(Color.blue)
                            .cornerRadius(20)
                            .padding(10)
                            .frame(width: quadrant, height: quadrant)
                    }
                }
                .background(Color.gray)
                .cornerRadius(10)
            }
        }.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width)
    }
}

struct ExampleView: View {
    
    var body: some View {
        
        CustomView {
            
//            Text("Item 1").id(1)
           
//            Text("Item 2").id(2)

//            Text("Item 3").id(3)

//            Text("Item 4").id(4)
            
        }
    }
}

我想到了诸如使用 AnyView 数组作为属性之类的事情,并尝试制作一个扩展视图函数,将视图本身附加到数组中,但这一切都让我更加困惑。

它会是什么样子的图片:

图片

标签: swiftviewswiftui

解决方案


如果您查看ViewBuilder文档,您会看到 Apple 的设置是每个接受View的 s 最多 10 个具有 1 个函数/初始化程序。

如果我要这样做,我会使用相同的模式(见CustomGridView2下文)。但是,如果您将View在示例中传递相同的内容,Text那么仅传递数据会更好、更安全。

struct CustomGridView1: View {
    var items: [String]
    var columns: [GridItem] =
        Array(repeating: .init(.flexible()), count: 2)
    
    var body: some View {
        ZStack {
            LazyVGrid(columns: columns) {
                ForEach(items.indices, id: \.self) {idx in
                    Rectangle()
                        .foregroundColor(.blue)
                        .overlay(
                            Text(items[idx]).id(idx)
                        )
                        .background(Color.blue)
                        .cornerRadius(20)
                        .padding(10)
                        .aspectRatio(1, contentMode: .fill)
                }
            }
            .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width)
            .background(Color.gray)
            .cornerRadius(10)
            
        }
    }
}
struct CustomGridView2<Content: View>: View {
    let content1: Content
    let content2: Content?
    let content3: Content?
    let content4: Content?
    var columns: [GridItem] =
        Array(repeating: .init(.flexible()), count: 2)
    
    init(@ViewBuilder _ content1: @escaping () -> Content) {
        self.content1 = content1()
        self.content2 = nil
        self.content3 = nil
        self.content4 = nil
    }
    init(@ViewBuilder _ content1: @escaping () -> Content, _ content2: @escaping () -> Content) {
        self.content1 = content1()
        self.content2 = content2()
        self.content3 = nil
        self.content4 = nil
    }
    init(@ViewBuilder _ content1: @escaping () -> Content, _ content2: @escaping () -> Content, _ content3: @escaping () -> Content) {
        self.content1 = content1()
        self.content2 = content2()
        self.content3 = content3()
        self.content4 = nil
    }
    init(@ViewBuilder _ content1: @escaping () -> Content, _ content2: @escaping () -> Content, _ content3: @escaping () -> Content, _ content4: @escaping () -> Content) {
        self.content1 = content1()
        self.content2 = content2()
        self.content3 = content3()
        self.content4 = content4()
    }
    var body: some View {
        ZStack {
            LazyVGrid(columns: columns) {
                
                content1
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(Color.blue)
                    .cornerRadius(20)
                    .padding(10)
                    .aspectRatio(1, contentMode: .fill)
                
                if content2 != nil{
                    
                    content2
                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                        .background(Color.blue)
                        .cornerRadius(20)
                        .padding(10)
                        .aspectRatio(1, contentMode: .fill)
                }
                if content3 != nil{
                    
                    content3
                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                        .background(Color.blue)
                        .cornerRadius(20)
                        .padding(10)
                        .aspectRatio(1, contentMode: .fill)
                }
                if content4 != nil{
                    
                    content4
                        .frame(maxWidth: .infinity, maxHeight: .infinity)
                        .background(Color.blue)
                        .cornerRadius(20)
                        .padding(10)
                        .aspectRatio(1, contentMode: .fill)
                }
            }
            .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.width)
            .background(Color.gray)
            .cornerRadius(10)
        }
    }
}
struct ExampleView2: View {
    var body: some View {
        CustomGridView2 {
            Text("Item 1").id(1)
            Text("Item 2").id(2)
            Text("Item 3").id(3)
            Text("Item 4").id(4)
        }
    }
}
struct ExampleView1: View {
    var body: some View {
        CustomGridView1(items: ["Item 1", "Item 2", "Item 3", "Item 4"])
    }
}

推荐阅读