Swift Array index assigned to variable? - ios

I want to find the array index of the selected element in a table and assign it to a variable.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
let kategorilerVC = KategoriController()
let kategoriIndexCode = firstList[indexPath.row]
print(kategoriIndexCode)
//self.present(kategorilerVC, animated: true)

The array index is indexPath.row, which is the same variable you are using to access the value of the array when you do this:
firstList[indexPath.row]
So in your code, you could do this:
let kategoriIndexCode = indexPath.row

Related

Swift 5 | didSelectRowAt is selecting two cells at the same time

I am doing a screen where there a list o cells with a switch, like an image below;
I have a struct where a save the label of the cell and the switch state value. This struct is loaded at: var source: [StructName] = [] and then source values are attributed to the UITableView cells.
The problem is that when a touch a cell the function: func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) change multiples cells switches states at the same time.
I try to work around the problem by implementing the following function:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let cell = tableView.cellForRow(at: indexPath) as! CustomTableViewCell
for n in 0..<source.count{ // This loop search for the right cell by looking at the cell label text and the struct where the state of the switch is saved
if cell.label.text! == source[n].Label{
// If the label text is equal to the position where the values is saved (is the same order that the cells are loaded in the UITableView) then a change the state of the switch
let indexLabel = IndexPath(row: n, section: 0)
let cellValues = tableView.cellForRow(at: indexLabel) as! CustomTableViewCell
if cellValues.switchButton.isOn {
cellValues.switchButton.setOn(false, animated: true)
source[n].valor = cellValues.switchButton.isOn
} else {
cellValues.switchButton.setOn(true, animated: true)
source[n].valor = cellValues.switchButton.isOn
}
break
}
}
although is saved the right values to the switch state array(source) the visual state of multiples switches also changes even though the cells where never touch.
How could I change my code to select and change only the touched cell?
You should not store / read the state of anything in a cell.
But first things first:
Why do loop through all the values? You should be able to access the row in the data model directly by indexPath.row
You should only modify the model data, not the cell
You then tell the table view to reload the cell, which will then ask the model for the correct data to be displayed.
I would suggest the following:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let row = indexPath.row
source[row].valor.toggle()
tableView.reloadRows(at:[indexPath], with:.automatic)
}

for loop only shows first item in array when trying to display in tableView

I'm trying to display tableview cells based on items in an array but for some strange reason it will only display the first item in the array. When I use a print statement it shows the array it being iterated through correctly.
Here is the array:
var restaurants = ["Truckyard", "EasySlider", "Revolver", "Armoury"]
Here is the cellForRowAtIndexPath:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = restaurantTableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! restaurantCell
for rest in restaurants {
cell.restaurantImageView.image = UIImage(named: rest)
cell.restaurantNameLabel.text = rest
}
return cell
}
cellForIndexPath is called once for each row. Try this instead:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = restaurantTableView.dequeueReusableCell(withIdentifier: reuseIdentifier, for: indexPath) as! restaurantCell
cell.restaurantImageView.image = UIImage(named: restaurants[indexPath.row])
cell.restaurantNameLabel.text = restaurants[indexPath.row]
return cell
}
No need for a loop. cellForRowAt is providing you with an indexPath. Check the indexPath.row property. If you only have one section, the row is the index of the item in your array you want to access. You are basically iterating over your array for each row and this will inevitably set your last item as the title/image

Cannot call value of non-function type: UITableView

I've a Swift class that extends from UITableViewController. It has this function
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {...}
There's need that, I need to call this function programatically at one place and when I write
self.tableView(tableView, cellForRowAt: 1)
I get, Cannot call value of non-function type 'UITableView!'
How can I call this function programatically?
You don't need to (you're not supposed to) call that delegate/datasource method directly. UITableView has a func for that:
tableView.cellForRow(at: indexPath)
Just create the index path based on your row, like:
let indexPath = IndexPath(row: 1, section: 0)
cellForRowAt takes an IndexPath, not an Int:
func someFunc(indexPath: IndexPath) {
let cell = tableView(tableView, cellForRowAt: indexPath)
print(cell)
}

Show data from array to array labels in tableview

i have the dictionary - dictTime: [Int:[Int]] and I'd like to show it in tableView in cell.
To show key in every cell - not a problem, but I'd like to show every element of value of dictionary in "own" UILabel, so I created [UILabel] and understand that count of UILabel in array must be equal count of elements in value of dictionary, but how to do it in func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell for showing for every row (row - it's key-[value])?
Assuming your dictionary is like [Int1: [Int2]], that means:
dictTime.allKeys will give you array of all Int1
dictTime[Int1] will give you respective [Int2]
Example:
var dictTime = [1: [1,2], 2: [2,3], 3: [3,4]]
For showing these in a tableView:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dictTime.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath)
let keys = Array (dictTime.keys)
cell.textLabel?.text = String (keys[indexPath.row])
cell.detailTextLabel?.text = String (dictTime[indexPath.row])
return cell
}
In func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell call an other function and pass your dictionary value to that function for example [1,2,3] also pass your tbaleviewcell to that function. Now in that function run a loop on your dictionary array [1,2,3] and one by one UILabel into your tableviewcell programmatically.
I am not sure I understand the problem. If you want to have as many rows as dictionary entries, use the following:
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dictTime.count
}
If you want to have as many labels in your cell, as entries for each key in your dictionary, you need to implement a complicated solution.
I would suggest creating a "super cell" which has the maximum amount of labels, put them in a stach view, and hide them according to the number of entries.

Populate UITableView with Dictionary data (Swift)

I'm making an social networking app with a NodeJS backend. The app gets its data from the MongoDB associated with the Node app with a GET request. I have figured out how to parse the JSON returned from the GET request as a native Dictionary, but can not find a clean way of turning each of the objects in the dictionary into a TableViewCell in my TableView. The Dictionary is basically this:
["username":"personWhoPosted", "taggedUsername":"personWhoIsTagged", "imageURL":"http://urlofimageposted.com"]
I need each of those to fill different values/labels inside the TableViewCells
If you want to utilize indexPath, I would keep a copy of array of dictionary keys.
func fetchData() {
// ....
// Your own method to get the dictionary from json
let self.userDict = ["username":"personWhoPosted", "taggedUsername":"personWhoIsTagged", "imageURL":"http://urlofimageposted.com"]
// Keep a copy of dictionary key
let self.userDictKeyCopy = Array(self.userDict.keys)
// You may want to sort it
self.userDictKeyCopy.sort({$0 < $1})
}
// Table view delegates
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.userDictKeyCopy.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(kCustomCell) as! CustomTableCell
// Assuming one section only
let title = self.userDictKeyCopy[indexPath.row] // e.g. "taggedUsername"
cell.titleLabel = title
cell.contentLabel = self.userDict[title] // e.g. "personWhoIsTagged"
return cell
}
let yourDict = ["username":"personWhoPosted", "taggedUsername":"personWhoIsTagged", "imageURL":"http://urlofimageposted.com"]
Number of rows in section
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return yourDict.count
}
Cell for row at
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let key = Array(yourDict)[indexPath.row].key
let value = yourDict[key]
return cell
}

Resources