我正在尝试从列表中的一个元素(dueTime)将我的表格视图单元格组织成部分。Firebase是我的后端,每个项目都有一个名为dueTime的子节点,其值为时间字符串。我已经创建了这些部分并使它们显示出来,但我需要实际的项目分开放置到它们所属的部分中。目前,当我运行我的代码时,只有这些部分显示出来。
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
let tasksRef = ref.childByAppendingPath("tasks")
tasksRef.observeSingleEventOfType(.Value, withBlock: {snapshot in
var dueTimesArray = [String]()
for task in snapshot.children.allObjects as! [FDataSnapshot] {
let times = task.value["dueTime"] as! String
dueTimesArray.append(times)
}
self.sectionTimes = dueTimesArray
})
let uniqueSectionTimes = Array(Set(sectionTimes))
return uniqueSectionTimes.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var uniqueSectionTimes = Array(Set(sectionTimes))
let tasksRef = Firebase(url: "\(self.ref)/tasks")
tasksRef.queryOrderedByChild("dueTime").queryEqualToValue(uniqueSectionTimes[section]).observeEventType(.Value, withBlock: { snapshot in
var newTasks = [Task]()
for task in snapshot.children.allObjects as! [FDataSnapshot] {
let tasks = Task(snapshot: task)
newTasks.append(tasks)
}
self.sectionTasks = newTasks
})
return self.sectionTasks.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! TaskCell
// Configure the cell...
cell.selectionStyle = .None
// let uniqueSectionTimes = Array(Set(sectionTimes))
// let times = self.sectionTasks[uniqueSectionTimes[indexPath.section]]
let task = tasks[indexPath.row]
cell.label.text = task.title
ref.childByAppendingPath("tasks").observeEventType(.Value, withBlock: { snapshot in
if task.done == true {
cell.checkBox.image = UIImage(named: "checkedbox")
cell.detailLabel.text = "Completed By: \(task.completedBy)"
}
else {
cell.checkBox.image = UIImage(named: "uncheckedbox")
cell.detailLabel.text = ""
}
})
cell.delegate = self
return cell
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let uniqueSectionTimes = Array(Set(sectionTimes))
return uniqueSectionTimes[section]
}
我觉得问题的根源可能在于numberOfRowsInSection和cellForRowAtIndexPath方法。在numberOfRowsInSection中,当我将self.sectionTasks设置为newTasks后,打印
self.sectionTasks
会输出6个数组(等于section的数量),每个数组中都有正确的任务。但是,当我打印self.sectionTasks.count
时,我六次都得到了'0',这对我来说没有意义。在cellForRowAtIndexPath中,我不知道该怎么做。我似乎找不到一个好的教程来解释它。更新1:
我也在numberOfRows中尝试过这个方法。
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var uniqueSectionTimes = Array(Set(sectionTimes))
let tasksRef = Firebase(url: "\(self.ref)/tasks")
tasksRef.queryOrderedByChild("dueTime").queryEqualToValue(uniqueSectionTimes[section]).observeEventType(.Value, withBlock: { snapshot in
var newTasks = [String]()
for task in snapshot.children.allObjects as! [FDataSnapshot] {
let tasks = task.value["title"] as! String
newTasks.append(tasks)
}
// for task in snapshot.children.allObjects as! [FDataSnapshot] {
// let tasks = Task(snapshot: task)
// newTasks.append(tasks)
// }
self.sectionTasks = newTasks
})
print(sectionTasks.count)
return self.sectionTasks.count
}
我得到了相同的结果。基本上,这种方法只给我每个数组中项目的标题,而不是整个项目。但它仍然告诉我所有数组的计数为0。
更新2:
在实现以下代码后,我现在在每个部分下都会获得所有任务的副本。我想我需要以某种方式过滤任务,但我不知道在哪里或如何做到这一点。
func queryDueTimes(uniqueSectionTimes:Array<String>) {
let tasksRef = Firebase(url: "\(self.ref)/tasks")
tasksRef.queryOrderedByChild("dueTime").observeEventType(.Value, withBlock: { snapshot in
var newTasks = [Task]()
for task in snapshot.children.allObjects as! [FDataSnapshot] {
let times = Task(snapshot: task)
newTasks.append(times)
}
self.sectionTasks = newTasks
print(self.sectionTasks)
self.tableView.reloadData()
})
}
我在
viewDidLoad()
中运行此函数,得到了一个包含每个任务元素的大数组。我想我需要使用numberOfRows
中的“section”元素,但我不确定如何操作。此外,我查看的教程展示了在cellForRow
中使用indexPath.section,但我不确定如何实现这两个操作。
解决方案:
最终,我彻底改变了查询代码,因此从本地数组中提取而不是从Firebase中提取。func querySections() -> [String] {
var sectionsArray = [String]()
for task in tasks {
let dueTimes = task.dueTime
sectionsArray.append(dueTimes)
}
let uniqueSectionsArray = Array(Set(sectionsArray)).sort()
return uniqueSectionsArray
}
func queryDueTimes(section:Int) -> [Task] {
var sectionItems = [Task]()
for task in tasks {
let dueTimes = task.dueTime
if dueTimes == querySections()[section] {
sectionItems.append(task)
}
}
return sectionItems
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return querySections().count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return queryDueTimes(section).count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! TaskCell
// Configure the cell...
cell.selectionStyle = .None
let times = queryDueTimes(indexPath.section)
let task = times[indexPath.row]
cell.label.text = task.title
if task.done == true {
cell.checkBox.image = UIImage(named: "checkedbox")
cell.detailLabel.text = "Completed By: \(task.completedBy)"
}
else {
cell.checkBox.image = UIImage(named: "uncheckedbox")
cell.detailLabel.text = ""
}
cell.delegate = self
return cell
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return querySections()[section]
}
observeEventType
函数是否也是如此?如果是的话,在任务填充之前你可能会返回一个计数。 (尝试在块内部再添加一个打印语句来确认事件的顺序。) - Phillip Mills