I am trying to retrieve the values of wInstockArray in a table view cell. Currently the the wInstockArray is empty I am inserting a string on a button click and appending in array. but when I retried the values in cellForRowAtIndexath method it gives error
Index out of range
What I have defined is :
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return wInstockArray.count + 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let firstCell = firstTableView.dequeueReusableCell(withIdentifier: "firstCell")! as UITableViewCell
if wInstockArray.count == 0 {
print("no widgets in instock")
} else {
firstCell.textLabel?.text = wInstockArray[indexPath.row]
print("\(wInstockArray.count)") //prints 1
return firstCell
}
}
inside button click action
wInstockArray.append(item)
Inside button click method, please reload your table.
YOUR_TABLE.reloadData()
and update this method,
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return wInstockArray.count
}
In numberOfRowsInSection method return wInstockArray array count
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return wInstockArray.count
}
Inside the button click action, reload the tableView
wInstockArray.append(item)
tableView.reloadData()
Related
After receiving a new object, I call this func to insert a cell:
private func addCellToTheTop(recipe: Recipe) {
guard let recipeTableView = self.recipeTableView else { return }
recipesForShow.insert(recipe, at: 0)
recipeTableView.beginUpdates()
recipeTableView.insertRows(at: [IndexPath.init(row: 0, section: 0)], with: .automatic)
recipeTableView.endUpdates()
}
But I get an error
Why the number of section does not match?
If it is important:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func numberOfSections(in tableView: UITableView) -> Int {
return recipesForShow.count
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return TableCellConfig.spaceBetweenCells
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = UIView()
headerView.backgroundColor = UIColor.clear
return headerView
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//...
}
You are getting this exception because you are appending a new element to the array that is being used to determine the numberOfSection whereas you are inserting a new row into the tableView. To fix this you need to insert section instead of inserting new row, here's how:
recipeTableView.insertSections([0], with: .automatic)
Whenever I run the app, the tableView has no data, waiting for user to input. The problem is that if the numberOfSections is 1, it works just fine, but when I change it to 2 it crashes because Index out of range
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "expenseCell") as? ExpenseCell else { return UITableViewCell() }
let budget = userBudget[indexPath.section][indexPath.row]
cell.delegate = self
cell.configureCell(budget: budget)
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.none
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userBudget[section].count // <- Crash here
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return "Practice with Sections \(section)"
}
It is because you are accessing index 1 of userBudget while i assume it contains 0 index only.
This crash happens cause your array userBudget, don't has two elements at the moment you try access his second position.
You must guard that userBudget has two elements on minimium...
You should that you must to assign value to userBudget on your ViewDidLoad.
You are saying that you will have two section to your tableView's delegate, but you have an array which contains only one array. Basically when you try to reach userBadget[1] in your numberOfRowsInSection function and it crashes because it doesn't exist.
Replace
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
With
func numberOfSections(in tableView: UITableView) -> Int {
return userBudget.count
}
I created a tableView section for each day in my app. In simulator when I add data from beginning (tableview empty) it shows OK all the data, the section's name is the day, everything OK but when I change the date from my settings and add a new input I get an error that when I create the cell, it's out of bounds. I set some prints to see if its out of bounds and it seems to be in bounds but I don't know why I get this error
Code:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "expenseCell") as? ExpenseCell else { return UITableViewCell() }
print("SECTION: \(daySections[indexPath.section].daySection)")
print("ROWS: \(daySections[indexPath.section].contentCount)")
let budget = userBudget[indexPath.section][indexPath.row] // <- error getting here
cell.delegate = self
cell.configureCell(budget: budget)
return cell
}
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
return true
}
func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.none
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Int(daySections[section].contentCount)
}
func numberOfSections(in tableView: UITableView) -> Int {
return daySections.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return daySections[section].daySection
}
Debug:
SECTION: Optional("21.10.2017")
ROWS: 2
SECTION: Optional("21.10.2017")
ROWS: 2
SECTION: Optional("22.10.2017")
ROWS: 1
fatal error: Index out of range
2017-10-16 15:41:30.284173+0300 Expense Manager[7877:380262] fatal error: Index out of range
(lldb)
I also set prints to show me indexPath.section and indexPath.row and when I get the error they are section: 1; row: 0.
I have UITableView with methods:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
override func numberOfSections(in tableView: UITableView) -> Int
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
So, the problem is that Xcode runs at first
override func numberOfSections(in tableView: UITableView) -> Int
which returns me 1.
Later it runs override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int which also returns me 1.
BUT I do not know why after these 2 methods it does not run cellForRowAt method and does not display any row on my UITableView.
I do not know what happens there and why this happens.
Have you met such problem and could you please help me to fix it?
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let fetchedResultsController = self.fetchedResultsController, let fetchedObjects = fetchedResultsController.fetchedObjects {
if !searchController.isActive {
print("numberOfRowsInSection fetchedObjects.count - \(fetchedObjects.count)")
return fetchedObjects.count
} else {
if let results = filteredResult[searchController.searchBar.selectedScopeButtonIndex] {
print("numberOfRowsInSection results.count - \(results.count)")
return results.count
}
}
}
print("numberOfRowsInSection - 0")
return 0
}
override func numberOfSections(in tableView: UITableView) -> Int {
if let frc = fetchedResultsController, frc.fetchedObjects?.count != 0 {
print("numberOfSections - 1")
return 1
} else {
print("numberOfSections - 0")
return 0
}
}
What is probably happening is that your cell has height 0. When this happens, cellForRowAt won't be called at all, even if the other methods return a non zero section/row count.
My guess as to why this is happening is that you may be using auto layout for your cell, but your constraints don't allow the cell to figure out its own height. You may be using auto layout unknowingly, since on iOS 11, it's now the default. If you are using storyboards you can set the height for the cell prototype on the attributes inspector, instead of checking the automatic box. Alternatively, you can set it in code with tableView.rowHeight or by implementing func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
I am trying to create a tableView for each value in my array and I am not sure how to go about creating that. The code below clearly doesn't work I just used it to illustrate my point. How do I differentiate between tables in the tableView protocol functions.
let array = ["1","2","3","4","5"]
for value in array{
let newTableView: UITableView()
//Continue with creation of table
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tableContent.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return cell
}
Any help is appreciated and please comment if the question is unclear
Previously, I have needed multiple TableViews or Collection Views in a single ViewController, e.g. for different tabs.
You can identify each table by using the tag property.
let data : [Int : [YourObjects]]
for key, value in data {
let newTableView: UITableView()
// Identify the table
newTableView.tag = key
newTableView.dataSource = self
//Continue with creation of table
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.data[tableView.tag].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue cell
// Get the data for this table, identified by the tag
let tableData = data[tableView.tag]
cell.populateCell(withData: tableData[indexPath.row])
return cell
}