While debugging I found that in my numberOfRowInSection it is always returning the count and skipping over the the if !DealsDataService.instance.getKellysDeals()[section].isExpanded
condition which is causing the error below since it wont return 0.
Would there be any reason why that condition would be getting skipped over?
Error: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (2), plus or minus the number of rows inserted or deleted from that section (0 inserted, 2 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
ViewController that is handling tableview and expanding and collapsing sections :
@IBOutlet weak var daysTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
daysTable.dataSource = self
daysTable.delegate = self
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let view = UIView()
view.backgroundColor = .black
let headerLabel = UILabel()
let button = UIButton(type: .system)
let headerList = DaysService.instance.getHeader()
headerLabel.textColor = .yellow
headerLabel.font = UIFont.boldSystemFont(ofSize: 20)
headerLabel.backgroundColor = .black
headerLabel.text = headerList[section]
button.setTitle("Close", for: .normal)
button.setTitleColor(.yellow, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
button.addTarget(self, action: #selector(handleOpenClose), for: .touchUpInside)
button.tag = section
headerLabel.frame = CGRect(x: 5, y: 7.5, width: 150, height: 25)
button.frame = CGRect(x: 150, y: 7.5, width: 150, height: 25)
view.addSubview(headerLabel)
view.addSubview(button)
return view
}
@objc func handleOpenClose(button: UIButton)
{
print("trying to expand....")
let section = button.tag
var dealsArray = DealsDataService.instance.getKellysDeals()
var indexPaths = [IndexPath]()
for deals in dealsArray[section].deals.indices
{
print(0, deals)
let indexPath = IndexPath(row: deals, section: section)
indexPaths.append(indexPath)
}
let isExpanded = dealsArray[section].isExpanded
dealsArray[section].isExpanded = !isExpanded
button.setTitle(isExpanded ? "Open" : "Close", for: .normal)
//still having problem expanding and closing
if isExpanded
{
dealsArray[section].deals.removeAll()
daysTable.deleteRows(at: indexPaths, with: .fade)
}
else
{
self.daysTable.insertRows(at: indexPaths, with: .fade)
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if !DealsDataService.instance.getKellysDeals()[section].isExpanded
{
return 0
}
return DealsDataService.instance.getKellysDeals()[section].deals.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return DealsDataService.instance.getKellysDeals().count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DaysCell", for: indexPath)
let deals = DealsDataService.instance.getKellysDeals()[indexPath.section].deals[indexPath.row]
cell.textLabel?.text = deals
return cell
}
Data service that returns the array of deals:
static let instance = DealsDataService()
private(set) public var barNames = [Bars]()
public var kellysDeals = [
ExpandableDeals(isExpanded: true, deals:["$2 Bud Lights", "$1 Tacos"]),//Monday
ExpandableDeals(isExpanded: true, deals:["$2 Budweiser","$2 Burgers"]),//Tuesday
ExpandableDeals(isExpanded: true, deals:["$3 Drafts","50 cent wings"]),//Wednesday
ExpandableDeals(isExpanded: true, deals:["$8 Coors pitchers","$5 Sandwiches"]),//Thursday
ExpandableDeals(isExpanded: true, deals:["No Deal"]),//Friday
ExpandableDeals(isExpanded: true, deals:["No Deal"]),//Saturday
ExpandableDeals(isExpanded: true, deals:["No Deal"])//Sunday
]
func getKellysDeals() -> [ExpandableDeals]
{
return kellysDeals
}
}
In handleOpenClose I am calling the DataService when I should be declaring a global array variable then using that in my handleOpenClose function.
var barDeals: [ExpandableDeals] = []
@IBOutlet weak var daysTable: UITableView!
override func viewDidLoad()
{
super.viewDidLoad()
daysTable.dataSource = self
daysTable.delegate = self
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let view = UIView()
view.backgroundColor = .black
let headerLabel = UILabel()
let button = UIButton(type: .system)
let headerList = DaysService.instance.getHeader()
headerLabel.textColor = .white
headerLabel.font = UIFont.boldSystemFont(ofSize: 20)
headerLabel.text = headerList[section]
button.setTitle("Open", for: .normal)
button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
button.addTarget(self, action: #selector(handleOpenClose), for: .touchUpInside)
button.tag = section
headerLabel.frame = CGRect(x: 5, y: 7.5, width: 150, height: 25)
button.frame = CGRect(x: 150, y: 7.5, width: 150, height: 25)
view.addSubview(headerLabel)
view.addSubview(button)
return view
}
@objc func handleOpenClose(button: UIButton)
{
let section = button.tag
self.daysTable.beginUpdates()
var indexPaths = [IndexPath]()
for deals in self.barDeals[section].deals.indices
{
let indexPath = IndexPath(row: deals, section: section)
indexPaths.append(indexPath)
}
let isExpanded = self.barDeals[section].isExpanded
self.barDeals[section].isExpanded = !isExpanded
button.setTitle(!isExpanded ? "Close" : "Open", for: .normal)
if isExpanded
{
daysTable.deleteRows(at: indexPaths, with: .fade)
}
else
{
daysTable.insertRows(at: indexPaths, with: .fade)
}
self.daysTable.endUpdates()
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if self.barDeals[section].isExpanded == false
{
return 0
}
return self.barDeals[section].deals.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return self.barDeals.count
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.