如何在moveRowAt之后删除空节:sourceIndexPath:?

时间:2018-01-11 14:47:10

标签: ios swift uitableview

将行拖到新部分后,如果源部分为空,我该如何删除此部分?

我的代码:

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。

3 个答案:

答案 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
    }