Different cell depending on the cell text - ios

I have the following situation. I am making a weather app and I am displaying the data in cells for a period of days. I have the following structure:
Day1
Min temperature
Max temperature
Day2
Min temperature
Max temperature
Day3
Min temperature
Max temperature
etc etc...
I am also using sections and the following functions:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "minimumTemperature")
cell?.textLabel?.text = "fooMinTemperature"
return cell!
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 10
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return // logic for getting the heading of the section
}
The problem comes that the override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
function can only return 1 cell at a time. So for example this function will get called two times now and add the minimum temperature two times. How can I add both the min and max temperatures.

Assuming you have some array of data where each element in the array represents one day, you would use the section to pick the data for the correct day. Then you use the row to choose between min or max temperature.
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "minimumTemperature") as! UITableViewCell
let data = myArrayOfDays[indexPath.section]
let temp = indexPath.row == 0 ? data.minimumTemp : data.maximumTemp
cell.textLabel?.text = "\(temp)"
return cell
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
override func numberOfSections(in tableView: UITableView) -> Int {
return myArrayOfDays.count
}
The variable names I used are clearly just examples. Update with your own as needed.
Your section header can show the day number.

Related

UITableView adjust number of rows to row count in StoryBoard

Hello, Im trying to automatically modify number of rows in my tableView to = the count in my Array. The data works fine and number of rows loads accordingly. However the table itself always shows 4 rows, it won't load more and won't show less even when less are loaded, just as you can see in the picture. Below is my script and settings.
extension FirstViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("click")
}
}
extension FirstViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// let a = UserDefaults.standard.integer(forKey: "RunwayRows")
// return a
return runways.count
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = runways[indexPath.row].ident1
print(runways.count)
return cell
}
}

UITableView Section Index Out Of Bounds but it's not really out of bounds

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
}

Strange issue with displaying cells in UITableView

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

fatal error: Index out of range swift

I am facing Index out of range issue in UITableView.
Below is my code :
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
//== Teble: number of tables ==============================//
func numberOfSections(in tableView: UITableView) -> Int {
return headerTitleArray.count
}
//== Teble rows: number of rows ==============================//
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return cellTitleMultiArray.count
}
//== Teble rows: data for each row ==============================//
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomTableViewCell
let text = cellTitleMultiArray[indexPath.section][indexPath.row]
cell.titleLabel.text = text
return cell
}
}
I am trying to solve this issue but couldn't .Please please help me solve this issue....
It looks like your cellTitleMultiArray is an array of arrays, where the outer array contains an entry for each section, and for each section, the inner array at that index contains entries for each row in that section.
Thus numberOfSections(in:) should probably return the number of entries in cellTitleMultiArray.
tableView(_:numberOfRowsInSection:) should probably return the number of entries in the cellTitleMultiArray sub-array at the current section. See if you can work out that bit of code.

How to add rows to specific section in tableview with dictionary?

I have a dictionary and importing information from my database. I need to put it specifically in the right section in my table view. All the information is provided, if you need more detail or code I will provide it.
Dictionary output ["March 27": ["do the dishes", "take out the trash"], "March 29": ["Walk the dog", "Water the plants"], "March 28": ["Clean the house"]]
var date = ["March 27", "March 28", "March 29"]
func numberOfSections(in tableView: UITableView) -> Int {
return date.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return date[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = table.dequeueReusableCell(withIdentifier: "cell") as! Chores
//Having trouble on what to do here
return cell
}
That's how you can do, I think this is self explanatory:
var output = ["March 27": ["do the dishes", "take out the trash"], "March 29": ["Walk the dog", "Water the plants"], "March 28": ["Clean the house"]]
var date = Array(output.keys)
func numberOfSections(in tableView: UITableView) -> Int {
return date.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return date[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return output[date[section]]?.count ?? 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = table.dequeueReusableCell(withIdentifier: "cell") as! Chores
var value = output[date[indexPath.section]]?[indexPath.row] ?? ""
cell.textLabel.text = value
return cell
}
// Edited in number of rows you have:
output[date[section]]?.count
it's exactly like this, this mostly gives you optionals but I will ignore it in this example:
let keyForSection = date[section]
let arrayOfStringsForKey = output[keyForSection]
let numberOfRows = arrayOfStringsForKey.count
you do similar stuff to get the actual value but instead of count you pass index of the row you want the value from
let value = arrayOfStringsForKey[rowNumber]

Resources