简体   繁体   English

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

[英]SwiftUI List with different cells per section

I'm trying to create a List of questions.我正在尝试创建一个问题列表。

I was planning to create a 'section' per question and have each row change upon the type我打算为每个问题创建一个“部分”,并根据类型更改每一行

Now I have a lot of different types of questions.现在我有很多不同类型的问题。

Let's say for example:比如说:

  1. Ask some text input询问一些文本输入
  2. Select from a picker从选择器中选择
  3. Multiple select (so simply show all options)多选(所以只需显示所有选项)

I have this kind of setup working in 'regular' iOS However, when trying to implement such a thing in SwiftUI, the preview keeps freeing, I can't seem to get the build working either.我有这种在“常规”iOS 中工作的设置但是,当尝试在 SwiftUI 中实现这样的事情时,预览不断释放,我似乎也无法使构建工作。 I don't really get any feedback from xcode.我真的没有从 xcode 得到任何反馈。

Example code:示例代码:

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()
    }
}

Is such a thing possible in SwiftUI ?这样的事情在 SwiftUI 中可能吗? What am I missing ?我错过了什么? Why is it freezing ?为什么会结冰?

Your code is confusing the Type checker.您的代码混淆了类型检查器。 If you let it build long enough Xcode will give you an error stating that the type checker could not be run in a reasonable amount of time.如果你让它构建足够长的时间,Xcode 会给你一个错误,指出类型检查器无法在合理的时间内运行。 I would report this as a bug to Apple, perhaps they can improve the type checker.我会将此作为错误报告给 Apple,也许他们可以改进类型检查器。 In the mean time you can get your code to work by simplifying the expression that the ViewBuiler is trying to work through.同时,您可以通过简化 ViewBuiler 试图处理的表达式来使您的代码工作。 I did it like this:我是这样做的:

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()
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM