Swift - 用 [String: [String: String]] 字典填充 UITableView

3

我是Swift的初学者,目前正在创建一个日记应用程序,向用户提出问题。我将用户输入存储如下:

dict = ["date": ["question1": "answer", "question2": "answer"]]

现在,我需要在一个表格视图中向用户展示这些数据,其中“date”是标题,“question1”是描述。
我在网上查看了一些资料,但是答案似乎都提到了“indexPath.row”,用于将信息输入到单元格中,但由于这是一个字符串的字典,我无法这样做。
谢谢你的帮助!

2
你可能需要查看UITableViewDelegateUITableViewDataSource的文档。这些协议用于为表视图提供数据和交互逻辑。 - waldrumpus
4个回答

5

与其使用字典数组,您应该考虑使用更好地表示数据的对象。

struct Question: {
    let question: String
    let answer: String
}

struct DiaryDay {
    let date: Date // Note this is a Date object, not a String
    let questions: [Question]
}

那么你需要的是:

然后你就有了

let diaryDays = DiaryDay(date: <date>, questions: 
    [Question(question: "question1": answer: "answer"),
     Question(question: "question2": answer: "answer")])

虽然代码有点多,但是从现在开始,您会发现更容易看到正在发生的事情。

看起来您应该每天为日记添加一个部分...

override func numberOfSections(in tableView: UITableView) -> Int {
    return diaryDays.count
}

然后每个问题一行...
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let diaryDay = diaryDays[section]
    return diaryDay.questions.count
}

然后配置您的单元格...

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // dequeue cell
    let diaryDay = diaryDays[indexPath.section]
    let question = diaryDay.questions[indexPath.row]    
    cell.question = question
    return cell
}

并在章节标题中显示日期...
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    let diaryDay = diaryDays[section]

    return // formatted diaryDay.date
}

1

在显示您使用的字典类型的数据之前,您需要进行一些准备工作。同时请记住,字典不是有序列表,因此数据将按系统的顺序打印。以下是一种方法:

var data = ["date1":["q1":"A1","q2":"A2","q3":"A3"],"date2":["q1":"A1","q2":"A2","q3":"A3"]] . //This is data from your example
var displayableData = [(title: String, qAndA: [(question: String, answer: String)])]() //this is what we will be needing


override func viewDidLoad() {
    super.viewDidLoad()

    //convert the whole dictionary to tuple
    displayableData = data.map { ($0.key, $0.value.map{ ($0.key, $0.value)})}

    //here we have converted the dictionary to what we need
}


override func numberOfSections(in tableView: UITableView) -> Int {
    return displayableData.count  
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return displayableData[section].qAndA.count
}

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 55.0
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
    let currentQA = displayableData[indexPath.section].qAndA[indexPath.row]
    cell.textLabel?.text = "\(currentQA.question) -> \(currentQA.answer)"
    return cell
}

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 30.0
}

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 30.0))
    view.backgroundColor = UIColor.lightGray
    let label = UILabel(frame: CGRect(x: 10, y: 0, width: view.bounds.width - 20, height: 30.0))
    label.text = displayableData[section].title
    view.addSubview(label)
    return view
}

This is the output


1
你可以直接使用字典而无需更改。

在使用之前,记得进行排序

let dict = ["date": ["question1": "answer", "question2": "answer"]]

章节数量

override func numberOfSections(in tableView: UITableView) -> Int {
    return dict.count  
}

标题

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return Array(dict)[section].key
}
中的行数
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let key = Array(dict)[section].key
    return dict[key]?.count ?? 0
}

单元格所在的行。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
   let key = Array(dict)[section].key
   if let questionsDict = dict[key] {
     let keyValue = Array(questionsDict)[indexPath.row]
     print("Question: \(keyValue.key), Answer: \(keyValue.value)")
   }
   return cell
}

0

您可以尝试使用map。这里Dictionary转换为字典数组。

let dict = ["date": ["question1": "answer", "question2": "answer"]]

if let value = dict["date"] {
    let v = value.map {
        ["question": $0.key, "answer": $0.value]
    }

    debugPrint(v)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接