Swift 2 - UITableView with Multi sections - swift

I created a table with three sections, each section should handle an Animal array
var firstAnimals = Animal
var secondAnimals = Animal and so on
I am having trouble in the cellForRowAtIndexPath function, I want it to insert the items of the arrays according to the right section. I tried this, but it doesn't work with the array. Please help!
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! myCell
if indexPath.section == 0 {
cell.title.text = firstAnimals[indexPath.row]
} else if indexPath.section == 1 {
cell.title.text = secondAnimals[indexPath.row]
} else {
cell.title.text = thirdAnimals[indexPath.row]
}
return cell
}

The recommended way is to use a nested array
let animals = [[firstAnimal1, firstAnimal2, firstAnimal3],
[secondAnimal1, secondAnimal2, secondAnimal3],
[thirdAnimal1, thirdAnimal2, thirdAnimal3]]
Then cellForRowAtIndexPath could look like
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! myCell
let animalSection = animals[indexPath.section]
let animal = animalSection[indexPath.row]
cell.title.text = animal.name
return cell
}
Alternatively use an array with the section names and a dictionary with an animal array for each section name respectively. The section name array can also be used as the section header names.

Related

Displaying two reusable cells in tableview - Swift 3

I have two custom reusable table view cells in my table view. The first cell, I would like it to be present at all times. The second cell and beyond, are returning a count that is being passed from mysql database.
// return the amount of cell numbers
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
// cell config
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row < 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! InfoCell
//set the data here
return cell
} else {
let Postcell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath) as! PostCell
let post = posts[indexPath.row]
let image = images[indexPath.row]
let username = post["user_username"] as? String
let text = post["post_text"] as? String
// assigning shortcuts to ui obj
Postcell.usernameLbl.text = username
Postcell.textLbl.text = text
Postcell.pictureImg.image = image
return Postcell
}
} // end of function
My first cell is there and so are the post.count, but for some reason the posts.count is missing one post and I believe this is because of the first cell. Can anybody help me with this? thanks in advance.
You need to adjust the value returned from numberOfRowsInSection to account for the extra row. And you would need to adjust the index used to access values from your posts array to deal with the extra row.
But a much better solution is to use two sections. The first section should be your extra row and the second section would be your posts.
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
} else {
return posts.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! InfoCell
//set the data here
return cell
} else {
let Postcell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath) as! PostCell
let post = posts[indexPath.row]
let image = images[indexPath.row]
let username = post["user_username"] as? String
let text = post["post_text"] as? String
// assigning shortcuts to ui obj
Postcell.usernameLbl.text = username
Postcell.textLbl.text = text
Postcell.pictureImg.image = image
return Postcell
}
}

How I can show only certain cells taken from Dictionary in a tableView in Swift

I am using a dictionary in order to fill a tableview.
Trying to appear only cells that have a certain userID, but it return also the cells that doesn't have this userID.
I have managed to count only the items from dictionary with the certain userID and if for example my dictionary has 8 entries and I need to show only the last 2 entries which have different userID, it returns 2 empty cells (which are the first 2 in the dictionary.
How I can get only the cells with the certain userID?
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
var returnCount:Int = 0
let currentUserId = NSUserDefaults.standardUserDefaults().stringForKey("userId")
for place in places {
if place["userID"] == currentUserId {
returnCount++
}
}
return returnCount
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let currentUserId = NSUserDefaults.standardUserDefaults().stringForKey("userId")
let currentPlacesUserId = places[indexPath.row]["userID"]
if currentPlacesUserId == currentUserId {
cell.textLabel!.text = places[indexPath.row]["name"]
cell.detailTextLabel?.text = places[indexPath.row]["issue"]
}
return cell
}
The fact is that you should not do this kind of logic inside de tableView delegate methods. Try getting the places from that userId when you load this array.
If you really want to proceed with the approach you are currently using try the following:
Not sure if this gonna work, but you are creating the cell even if it doesnt have the user Id you want. Try this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let currentUserId = NSUserDefaults.standardUserDefaults().stringForKey("userId")
let currentPlacesUserId = places[indexPath.row]["userID"]
if currentPlacesUserId == currentUserId {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
cell.textLabel!.text = places[indexPath.row]["name"]
cell.detailTextLabel?.text = places[indexPath.row]["issue"]
return cell
} else{
return nil
}
}

Trouble passing tableview cell value to delete cell

I am trying to pass a value to update a tableview cell. Problem is I am not able to get the value. The tableview cell code is:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell;
// Gets staff name and puts it in the cell title
var sectionTitle:String = aventurasUnicas.objectAtIndex(indexPath.section) as String
var sectionStaff:Array = porAventura[sectionTitle]!
let staffNic:String = sectionStaff[indexPath.row] as String
cell.textLabel?.text = staffNic
// Gets the subtitle
var subtituloAventura:String = "\(sectionTitle).\(staffNic)" as String
var sectionStaff2:Array = subtituloTabla[subtituloAventura]!
let staffNic2:String = sectionStaff2[0] as String
cell.detailTextLabel?.text = staffNic2
cell.accessoryType = UITableViewCellAccessoryType.DetailButton
return cell
}
And the code I am stuck with is:
override func tableView(tableView: UITableView?, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath?) {
if (editingStyle == UITableViewCellEditingStyle.Delete) {
// I AM STUCK HERE
}
}
I want to get the staffNic for the next part of the program. Thanks for your help
Why not go this way - the way you get it is the way you set it:
let sectionTitle:String = aventurasUnicas.objectAtIndex(indexPath.section) as String
let sectionStaff:Array = porAventura[sectionTitle]!
//the text of the deleted row based on your datasource
let staffNic = sectionStaff[indexPath.row] as String
Or get it as cell's text:
let cell = tableView.cellForRowAtIndexPath(indexPath)!
let staffNic = cell.textLabel!.text!

Swift: How to make a selected cell NSLog the corresponding value and key from a dictionary

I have a TableViewController that is populated by a dictionary. My goal is that when I click a cell from the tableView it will NSLog the cell's name from the dictionary as well as the corresponding value.
For example if I have a dictionary:
var profiles = ["Joe": 1, "Sam": 2, "Nancy": 3, "Fred": 4, "Lucy": 5]
When I click the Sam it would show up "Sam. 2" or something like that.
Any help would be great.
Here's a sample of my code (TableView) :
class ProfileTableViewController: UITableViewController {
var person = people ()
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let row = indexPath.row
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell
let myRowKey = person.typeList[row]
let myRowData = person.profiles[myRowKey]
cell.textLabel!.text = myRowKey
cell.textLabel?.text = String(myRowKey)
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Here's where I'm at
}
Here's my swift file:
class people {
var profiles = ["Joe": 1, "Sam": 2, "Nancy": 3, "Fred": 4, "Lucy": 5]
var typeList:[String] { //computed property 7/7/14
get{
return Array(profiles.keys)
}
}
So, ideally, you want to use the index path that the method provides to grab whatever cell was selected.
Once you have that, you can extract the text from the cell and check with the dictionary.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Lots of optional chaining to make sure that nothing breaks
if let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath) { // Get the cell
if let cellTextLabel: UILabel = cell.textLabel { // Get the cell's label
if let name: String = cellTextLabel.text { // Get the text from its label
println("\(name): \(profiles[name])") // Check with the dictionary and print out the corresponding value
}
}
}
}
I would get the text in the label and use it to search the dictionary as such:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Get the cell for that indexPath
var cell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell!
// Get that cell's labelText
let myKey = cell.textLabel?.text
// Output the key and it's associated value from the dictionary
println("\(myKey): \(person.typeList[myKey])")
}

How to add two custom cell into tableview in storyboard in Swift?

I have a tableView with two different custom cell. One cell have a switch and other a image, I have Two separated custom class for the cells, identifiers.. but I can't see this. i don't know if I need change the configuration in story board to dynamic or other thing.. Can I show two different custom cells
Thanks!
Check the criteria for showing each specific custom cell, then cast to that cell as needed:
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
if (criteria for cell 1) {
let cell = tableView!.dequeueReusableCellWithIdentifier("cell1", forIndexPath: indexPath) as? Cell1
return (cell)
}
else {
let cell = tableView!.dequeueReusableCellWithIdentifier("cell2", forIndexPath: indexPath) as? Cell2
return (cell)
}
}
Swift 3
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath -> UITableViewCell {
if (criteria for cell 1) {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell1", for: indexPath) as! Cell1
return cell
}
else {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell2", for: indexPath) as! Cell2
return cell
}
}
override func tableView(tableView: UITableView?,cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
if (...) {
let cell : Mycell1 = tableView!.dequeueReusableCellWithIdentifier("Mycell1", forIndexPath: indexPath) as? Mycell1
return cell
}
else {
let cell : Mycell2 = tableView!.dequeueReusableCellWithIdentifier("Mycell2", forIndexPath: indexPath) as? Mycell2
return cell
}
}