NSInternalInconsistencyException 更新 Tableview
NSInternalInconsistencyException updating Tableview
我实现了一个 tableView 来折叠和展开行;这是我的 class(我遵循了 this 教程):
import UIKit
import ChameleonFramework
class AllTeamChantsController: UIViewController, UITableViewDataSource, UITableViewDelegate
{
var ponte: String?
var sections: [Section]!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
if let stringaPonte = ponte
{
title = stringaPonte
}
sections = [Section(name: "Derby", items: ["coro", "coro", "coro", "coro"]),
Section(name: "Personagi", items: ["coro", "coro", "coro", "coro"]),
Section(name: "Cori", items: ["coro", "coro", "coro", "coro"])]
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
var count = sections.count
for section in sections
{
count += section.items.count
}
return count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let section = getSectionIndex(indexPath.row)
let row = getRowIndex(indexPath.row)
if row == 0
{
let cell = tableView.dequeueReusableCell(withIdentifier: "header") as! AllTeamChantsHeader
cell.titleLabel.text = sections[section].name
cell.toogleButton.tag = section
cell.toogleButton.setTitle(sections[section].collapsed! ? "+" : "-", for: UIControlState())
cell.toogleButton.addTarget(self, action: #selector(AllTeamChantsController.toggleCollapse), for: .touchUpInside)
return cell
}
else
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as UITableViewCell!
cell?.textLabel?.text = sections[section].items[row - 1]
return cell!
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
let section = getSectionIndex((indexPath as NSIndexPath).row)
let row = getRowIndex((indexPath as NSIndexPath).row)
if row == 0
{
return 50.0
}
return sections[section].collapsed! ? 0 : 44.0
}
// MARK: - Event Handlers
func toggleCollapse(_ sender: UIButton) {
let section = sender.tag
let collapsed = sections[section].collapsed
// Toggle collapse
sections[section].collapsed = collapsed!
let indices = getHeaderIndices()
let start = indices[section]
let end = start + sections[section].items.count
tableView.beginUpdates()
for i in start ..< end + 1 {
tableView.reloadRows(at: [IndexPath(row: i, section: 1)], with: .automatic)
}
tableView.endUpdates()
}
// MARK: - Helper Functions
func getSectionIndex(_ row: NSInteger) -> Int {
let indices = getHeaderIndices()
for i in 0..<indices.count {
if i == indices.count - 1 || row < indices[i + 1] {
return i
}
}
return -1
}
func getRowIndex(_ row: NSInteger) -> Int {
var index = row
let indices = getHeaderIndices()
for i in 0..<indices.count {
if i == indices.count - 1 || row < indices[i + 1] {
index -= indices[i]
break
}
}
return index
}
func getHeaderIndices() -> [Int] {
var index = 0
var indices: [Int] = []
for section in sections {
indices.append(index)
index += section.items.count + 1
}
return indices
}
}
问题是,当我触摸切换按钮时,我的应用程序崩溃并且 Xcode 在控制台中向我发送此消息
"Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row X from section 1, but there are only 1 sections before the update".
谁能帮我解决这个问题?我只是试着查看 numberOfRowsInSection
和 toggleCollapse
方法,但没有发现任何问题。
我认为你的错误是
var count = sections.count // Wrong
for section in sections {
count += section.items.count
}
所以它将 return 15 行但它必须是 return 12 行所以尝试
var count = 0 // Then calculate all section count
它会 return 12 是的
希望这会有所帮助
这是错误的:
for i in start ..< end + 1 {
tableView.reloadRows(at: [IndexPath(row: i, section: 1)], with: .automatic)
}
显然,如果我删除第一部分,我必须在第 0 部分而不是第 1 部分重新加载 indexPath!这解决了崩溃问题!
我实现了一个 tableView 来折叠和展开行;这是我的 class(我遵循了 this 教程):
import UIKit
import ChameleonFramework
class AllTeamChantsController: UIViewController, UITableViewDataSource, UITableViewDelegate
{
var ponte: String?
var sections: [Section]!
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
if let stringaPonte = ponte
{
title = stringaPonte
}
sections = [Section(name: "Derby", items: ["coro", "coro", "coro", "coro"]),
Section(name: "Personagi", items: ["coro", "coro", "coro", "coro"]),
Section(name: "Cori", items: ["coro", "coro", "coro", "coro"])]
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
var count = sections.count
for section in sections
{
count += section.items.count
}
return count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let section = getSectionIndex(indexPath.row)
let row = getRowIndex(indexPath.row)
if row == 0
{
let cell = tableView.dequeueReusableCell(withIdentifier: "header") as! AllTeamChantsHeader
cell.titleLabel.text = sections[section].name
cell.toogleButton.tag = section
cell.toogleButton.setTitle(sections[section].collapsed! ? "+" : "-", for: UIControlState())
cell.toogleButton.addTarget(self, action: #selector(AllTeamChantsController.toggleCollapse), for: .touchUpInside)
return cell
}
else
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as UITableViewCell!
cell?.textLabel?.text = sections[section].items[row - 1]
return cell!
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
let section = getSectionIndex((indexPath as NSIndexPath).row)
let row = getRowIndex((indexPath as NSIndexPath).row)
if row == 0
{
return 50.0
}
return sections[section].collapsed! ? 0 : 44.0
}
// MARK: - Event Handlers
func toggleCollapse(_ sender: UIButton) {
let section = sender.tag
let collapsed = sections[section].collapsed
// Toggle collapse
sections[section].collapsed = collapsed!
let indices = getHeaderIndices()
let start = indices[section]
let end = start + sections[section].items.count
tableView.beginUpdates()
for i in start ..< end + 1 {
tableView.reloadRows(at: [IndexPath(row: i, section: 1)], with: .automatic)
}
tableView.endUpdates()
}
// MARK: - Helper Functions
func getSectionIndex(_ row: NSInteger) -> Int {
let indices = getHeaderIndices()
for i in 0..<indices.count {
if i == indices.count - 1 || row < indices[i + 1] {
return i
}
}
return -1
}
func getRowIndex(_ row: NSInteger) -> Int {
var index = row
let indices = getHeaderIndices()
for i in 0..<indices.count {
if i == indices.count - 1 || row < indices[i + 1] {
index -= indices[i]
break
}
}
return index
}
func getHeaderIndices() -> [Int] {
var index = 0
var indices: [Int] = []
for section in sections {
indices.append(index)
index += section.items.count + 1
}
return indices
}
}
问题是,当我触摸切换按钮时,我的应用程序崩溃并且 Xcode 在控制台中向我发送此消息
"Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to delete row X from section 1, but there are only 1 sections before the update".
谁能帮我解决这个问题?我只是试着查看 numberOfRowsInSection
和 toggleCollapse
方法,但没有发现任何问题。
我认为你的错误是
var count = sections.count // Wrong
for section in sections {
count += section.items.count
}
所以它将 return 15 行但它必须是 return 12 行所以尝试
var count = 0 // Then calculate all section count
它会 return 12 是的 希望这会有所帮助
这是错误的:
for i in start ..< end + 1 {
tableView.reloadRows(at: [IndexPath(row: i, section: 1)], with: .automatic)
}
显然,如果我删除第一部分,我必须在第 0 部分而不是第 1 部分重新加载 indexPath!这解决了崩溃问题!