问题
I have TableView inside a ViewController that is populated using JSON data:
The following is the structure of the JSON including sections:
struct TabSections {
let name : String
let collection : [TabCollection]
}
struct TabCollection: Decodable {
let number, person, status: String
let maker: String
}
The following is how the TableView and tabs populate with the JSON data:
var sections = [TabSection]()
private func fetchJSON() {
guard let url = URL(string: "https://example.com/example/example.php"),
let value = name.addingPercentEncoding(withAllowedCharacters: .urlQueryValueAllowed)
else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = "name=\(value)".data(using: .utf8)
URLSession.shared.dataTask(with: request) { data, _, error in
guard let data = data else { return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let res = try decoder.decode([TabCollection].self, from: data)
let grouped = Dictionary(grouping: res, by: { $0.status })
let keys = grouped.keys.sorted()
self.sections = keys.map({TabSections(name: $0, collection: grouped[$0]!)})
DispatchQueue.main.async {
self.receiptTableView.reloadData()
}
}
catch {
print(error)
}
}.resume()
}
The error occurs under numberOfRowsInSection
and stops on the first line where section is defined:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let section = sections[section]
return section.collection.count
}
I cannot seem to understand why I receiving Index out of range
on the line let section
回答1:
Most likely you don't have a numberOfSections
method which means the table view defaults to 1 section. Since your data model can have no elements initially, you need to implement numberOfSections
to return the number of elements in sections
.
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
回答2:
You can use that extension for Collection
fo safely retrieving an element from collection.
extension Collection {
/// Returns the element at the specified index if it is within bounds, otherwise nil.
subscript (safe index: Index) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}
So your numberOfRowsInSection
will look like that:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let section = sections[safe: section] else {
return 0
}
return section.collection.count
}
来源:https://stackoverflow.com/questions/57468112/index-out-of-range-error-when-creating-sections-in-tableview