将行拖到新部分后,如果源部分为空,我该如何删除此部分?
我的代码:
var exerciseSets = [Array<Exercise>]()
func numberOfSections(in tableView: UITableView) -> Int {
return self.exerciseSets.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let set = self.exerciseSets[section]
return set.count
}
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
var sourceSet = self.exerciseSets[sourceIndexPath.section]
let sourceExercise = sourceSet[sourceIndexPath.row]
var destinationSet = self.exerciseSets[destinationIndexPath.section]
destinationSet.insert(sourceExercise, at: destinationIndexPath.row)
sourceSet.remove(at: sourceIndexPath.row)
if sourceSet.count == 0 {
self.exerciseSets.remove(at: sourceIndexPath.section)
}
}
exerciseSets
有一组Exercise
个对象来填充每个部分的行。移动单元格时,我更新数据源,删除一个部分(来自exerciseSets
数组),如果它现在为空。
如果某个部分为空且数据源已更新以反映部分数量减少,我仍然在屏幕上留下一个空部分。在moveRowAt
崩溃中重新加载tableView。
答案 0 :(得分:1)
我尝试实现一个最小的工作示例来测试它是如何工作的。以下是一个工作示例,确实使用了我之前建议的deleteSections
:
import UIKit
class Table: UITableViewController {
var excerciseSets: [[String]] = [
["Mama", "Tato", "Baba"],
["1", "2", "3"],
["a", "b", "c"],
]
override func viewDidLoad() {
super.viewDidLoad()
tableView.setEditing(true, animated: false)
}
override func numberOfSections(in tableView: UITableView) -> Int {
return excerciseSets.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return excerciseSets[section].count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel?.text = excerciseSets[indexPath.section][indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch section {
case 0:
return "Family"
case 1:
return "Numbers"
case 2:
return "Letters"
default:
fatalError()
}
}
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
return true
}
override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
var sourceSet = self.excerciseSets[sourceIndexPath.section]
let sourceExercise = sourceSet[sourceIndexPath.row]
var destinationSet = self.excerciseSets[destinationIndexPath.section]
destinationSet.insert(sourceExercise, at: destinationIndexPath.row)
sourceSet.remove(at: sourceIndexPath.row)
// I had to update sets back, because an array of value types acts like a value type
// when I created variables destinationSet and sourceSet, arrays were copied, therefore
// so far I haven't really changed the model in self.excerciseSets
self.excerciseSets[destinationIndexPath.section] = destinationSet
self.excerciseSets[sourceIndexPath.section] = sourceSet
if sourceSet.count == 0 {
self.excerciseSets.remove(at: sourceIndexPath.section)
// Remove the section
tableView.beginUpdates()
tableView.deleteSections([sourceIndexPath.section], with: .none)
tableView.endUpdates()
}
}
}
现在特别注意moveRowAt
中的这些行:
// I had to update sets back, because an array of value types acts like a value type
// when I created variables destinationSet and sourceSet, arrays were copied, therefore
// so far I haven't really changed the model in self.excerciseSets
self.excerciseSets[destinationIndexPath.section] = destinationSet
self.excerciseSets[sourceIndexPath.section] = sourceSet
在我意识到模型没有真正更新之前,有一些奇怪的行为。如果您的模型(Exercise
)是struct
,它也是一种值类型,除非您重新分配数组,否则通过移动行并不会真正更新模型。
检查您的代码并检查是否不是这种情况。
答案 1 :(得分:0)
在 moveRowAt
结束时尝试此操作 DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
self.tableView.reloadData()
}
答案 2 :(得分:0)
您可以将部分标题高度设置为zsro,而不是实际删除该部分。
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if list.isEmpty {
return 0
}
return 42
}