表视图批处理操作的奇怪行为

时间:2016-06-17 11:57:08

标签: ios uitableview

准备工作:

  1. 创建新的单一视图项目
  2. 将视图控制器嵌入导航控制器
  3. 将两个条形按钮项拖到导航栏上
  4. 将表视图拖到根视图上,使视图控制器成为表视图的数据源
  5. 我的代码如下:

    import UIKit
    
    class ViewController: UIViewController {
        @IBOutlet weak var tableView: UITableView!
        var sec = [["00", "01", "02"],
                   ["10", "11", "12"]]
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    
    extension ViewController: UITableViewDataSource {
        func numberOfSectionsInTableView(tableView: UITableView) -> Int {
            return sec.count
        }
    
        func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return sec[section].count
        }
    
        func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
            cell.textLabel?.text = sec[indexPath.section][indexPath.row]
            return cell
        }
    }
    
    extension ViewController {
        @IBAction func deleteUpSection(sender: UIBarButtonItem) {
            sec[1][0] = "something else"
            sec.removeAtIndex(0)
            let deletedIndexPaths = [NSIndexPath(forRow: 0, inSection: 0), NSIndexPath(forRow: 1, inSection: 0),NSIndexPath(forRow: 2, inSection: 0)]
            let deletedIndexSet = NSIndexSet(index: 0)
            let reloadedIndexPaths = [NSIndexPath(forRow: 0, inSection: 1)]
            tableView.beginUpdates()
            tableView.deleteRowsAtIndexPaths(deletedIndexPaths, withRowAnimation: .Fade)
            tableView.deleteSections(deletedIndexSet, withRowAnimation: .Right)
            tableView.reloadRowsAtIndexPaths(reloadedIndexPaths, withRowAnimation: .Automatic)
            tableView.endUpdates()
        }
    
        @IBAction func deleteDownSection(sender: UIBarButtonItem) {
            sec[0][0] = "something else"
            sec.removeAtIndex(1)
            let deletedIndexPaths = [NSIndexPath(forRow: 0, inSection: 1), NSIndexPath(forRow: 1, inSection: 1), NSIndexPath(forRow: 2, inSection: 1)]
            let deletedIndexSet = NSIndexSet(index: 1)
            let reloadedIndexPaths = [NSIndexPath(forRow: 0, inSection: 0)]
            tableView.beginUpdates()
            tableView.deleteRowsAtIndexPaths(deletedIndexPaths, withRowAnimation: .Fade)
            tableView.deleteSections(deletedIndexSet, withRowAnimation: .Right)
            tableView.reloadRowsAtIndexPaths(reloadedIndexPaths, withRowAnimation: .Automatic)
            tableView.endUpdates()
        }
    }
    

    deleteDownSection按预期工作,但deleteUpSection崩溃,它们几乎相同。

    我发现的东西:

    • 如果我删除deleteRowsAtIndexPath中的deleteUpSection,它会按预期工作,同时执行删除和更新。
    • 如果我删除reloadRowsAtIndexPath中的deleteUpSection,则会成功删除上一部分。

    欢迎任何意见。

1 个答案:

答案 0 :(得分:0)

reloadRowsAtIndexPaths失败,因为您尝试重新加载不再存在的部分中的行(NSIndexPath(forRow: 0, inSection: 1))。您在先前的语句中删除了第0部分和第0部分本身的行,这意味着只剩下一个部分(即旧部分1现在是部分0)。

我猜你何时删除deleteRowsAtIndexPath并且它的工作原理是因为即使您删除了下一个语句中的部分,这些行仍会在某处暂时被引用,因此在调用reloadRowsAtIndexPaths时即使它的部分被删除,它也不会找不到这些行。