每个部分具有不同单元格的 SwiftUI 列表

SwiftUI List with different cells per section

我正在尝试创建问题列表。

我计划为每个问题创建一个 'section' 并根据类型更改每一行

现在我有很多不同类型的问题。

让我们举个例子:

  1. 询问一些文本输入
  2. Select 来自选择器
  3. 多个select(所以只显示所有选项)

我在 'regular' iOS 中使用了这种设置 然而,当试图在 SwiftUI 中实现这样的东西时,预览一直在释放,我似乎也无法让构建工作。我真的没有从 xcode.

那里得到任何反馈

示例代码:

import SwiftUI

struct Question: Hashable, Codable, Identifiable {
    
    var id: Int
    var label: String
    var type: Int
    var options: [Option]?
    var date: Date? = nil
}

struct Option : Hashable, Codable, Identifiable {
    var id: Int
    var value: String
}

struct MyList: View {
    
    
    var questions: [Question] = [
        Question(id: 1, label: "My first question", type: 0),
        Question(id: 2, label: "My other question", type: 1, options: [Option(id: 15, value: "Yes"), Option(id: 22, value: "No")]),
        Question(id: 3, label: "My last question", type: 2, options: [Option(id: 4, value: "Red"), Option(id: 5, value: "Green"), Option(id: 6, value: "Blue")])
    ]
    
    var body: some View {
        List {
            ForEach(questions) { question in
                Section(header: Text(question.label)) {

                    if(question.type == 0)
                    {
                        Text("type 0")
                        //Show text entry row
                    }
                    else if(question.type == 1)
                    {
                        Text("type 1")
                        //Show a picker containing all options
                    }
                    else
                    {
                        Text("type 2")
                        //Show rows for multiple select

//
//                    IF YOU UNCOMMENT THIS, IT STARTS FREEZING
//
//                        if let options = question.options {
//                            ForEach(options) { option in
//                                Text(option.value)
//                            }
//                        }
                    }
                    
                }
            }
        }
    }
}

struct MyList_Previews: PreviewProvider {
    static var previews: some View {
        MyList()
    }
}

在 SwiftUI 中可以实现这样的功能吗? 我错过了什么? 为什么会结冰?

您的代码混淆了类型检查器。如果你让它构建的时间足够长,Xcode 会给你一个错误,指出类型检查器不能在合理的时间内 运行。我会将此作为错误报告给 Apple,也许他们可以改进类型检查器。同时,您可以通过简化 ViewBuiler 尝试处理的表达式来让您的代码正常工作。我是这样做的:

import SwiftUI

struct Question: Hashable, Codable, Identifiable {
    var id: Int
    var label: String
    var type: Int
    var options: [Option]?
    var date: Date? = nil
}

struct Option : Hashable, Codable, Identifiable {
    var id: Int
    var value: String
}

struct Type0View : View {
    let question : Question

    var body : some View {
        Text("type 0")
    }
}

struct Type1View : View {
    let question : Question

    var body : some View {
        Text("type 1")
    }
}

struct Type2View : View {
    let question : Question

    var body : some View {
        Text("type 1")

        if let options = question.options {
            ForEach(options) { option in
                Text(option.value)
            }
        }
    }
}

struct ContentView: View {
    var questions: [Question] = [
        Question(id: 1, label: "My first question", type: 0),
        Question(id: 2, label: "My other question", type: 1, options: [Option(id: 15, value: "Yes"), Option(id: 22, value: "No")]),
        Question(id: 3, label: "My last question", type: 2, options: [Option(id: 4, value: "Red"), Option(id: 5, value: "Green"), Option(id: 6, value: "Blue")])
    ]

    var body: some View {
        List {
            ForEach(questions) { question in
                Section(header: Text(question.label)) {


                    if(question.type == 0)
                    {
                        Type0View(question: question)
                    }
                    else if(question.type == 1)
                    {
                        Type1View(question: question)
                    }
                    else
                    {
                        Type2View(question: question)
                    }

                }
            }
        }
    }
}

struct MyList_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}