my dataSource is empty, so it crash. it worked well in iOS 14
[iOS 15]The tableView(_:numberOfRowsInSection:) is called before the numberOfSections(in tableView: UITableView)
How do you set the dataSource
of the table view? On the storyboard? Or setting it in viewDidLoad()
with code?
i just define the dataSource in the Class
You said:
i just define the dataSource in the Class
Are you also settings the tableView's datasource to this property?
(It looks like you aren't)
Otherwise...
For both functions, zero is a valid return value...
...so that suggests there may be a problem with the property you are accessing?
You said:
my dataSource is empty
It's not clear what you mean by this.
If it's really empty, isn't a crash an appropriate response?
• Are you sure that both methods are being called?
• Have you checked the Int value that they return?
• Are you checking to see that datasource[section] exists, before you reference it?!
you declare
var dataSource = [Merchant]()
So it is empty.
Then you should crash when calling dataSource[section] where section is zero.
I do not see where you populate the dataSource.
Thanks for your replies, finally i find if i set tableView.tableHeaderView
, tableView.estimatedSectionHeaderHeight
tableView.delegate = self
and tableView.dataSource = self
before setting tableView.frame, it will call numberOfRowsInSection
first and get the Index out of range
error.
Then i place tableView.delegate = self
and tableView.dataSource = self
below the tableView.frame
, it calls numberOfSections
first and do not call numberOfRowsInSection
. Commenting one of the tableView.tableHeaderView
and tableView.estimatedSectionHeaderHeight
also work well.
this is the complete code.
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let dataSource = [[String]]()
let tableView = UITableView(frame: .zero, style: .plain)
override func viewDidLoad() {
super.viewDidLoad()
let bounds = UIScreen.main.bounds
tableView.tableHeaderView = UIView()
// tableView.tableFooterView = UIView()
tableView.estimatedSectionHeaderHeight = 0
// tableView.estimatedSectionFooterHeight = 0
// before frame
tableView.delegate = self
tableView.dataSource = self
tableView.frame = CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height)
// after frame
// tableView.delegate = self
// tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
view.addSubview(tableView)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataSource[section].count
}
func numberOfSections(in tableView: UITableView) -> Int {
return dataSource.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
return cell
}
}