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

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])")
}

Related

UICollectionView inside UITableViewCell how pass data to Uicollectionviewcell

I have a tableview controller with a collectionview inside it , in the tableviewcell i implemented a collection view with horizontal scrolling, the data appears not correct
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = friendsCollectionView.dequeueReusableCell(withReuseIdentifier: "friends", for: indexPath) as! friendCollectioncell
friendsCollectionView.delegate = self
friendsCollectionView.dataSource = self
let ava = Myfriends[indexPath.item]["ava"] as! String
let firstname = Myfriends[indexPath.row]["firstName"] as! String
let lastname = Myfriends[indexPath.row]["lastName"] as! String
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return Myfriends.count
}
problem is in
return Myfriends.count
always empty so not thing appears but if a change to 1 or 2. it works ok
in uitableviewcontroller:
var myFriends: [Dictionary<String, Any>] = []
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// section 1 which includes 1 cell that shows my friends
if indexPath.section == 0 {
// accessing cell in main.storyboard that has id "friends". This cell stores my friends
let cell = tableView.dequeueReusableCell(withIdentifier: "friends", for: indexPath) as! friends
cell.Myfriends = myFriends
}
return cell
// section 2 (or any other sections) that shows all the posts of the user
} else {
return cell
}
Thank You in advance
Edit:
If I understand this right:
problem is in return Myfriends.count always empty so not thing appears but if a change to 1 or 2. it works ok
probably your collectionView(_:numberOfItemsInSection:) is called before you this cell.Myfriends = myFriends is set.
In your friends tableViewCell:
class friends: UITableViewCell .. {
...
var Myfriends: [Friend] {
didSet {
friendsCollectionView.reloadData()
}
}
}
Imho your collectionView(_:numberOfItemsInSection:) isn't called at all.
This code
friendsCollectionView.delegate = self
friendsCollectionView.dataSource = self
in your collectionView(_:cellForItemAt:) is useless, because if this method is called, dataSource (and probably delegate) are already set correctly.
Instead, change your tableView(_:cellForRowAt:) to
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView...
cell.friendsCollectionView.delegate = cell
cell.friendsCollectionView.dataSource = cell
return cell
} else {
...
}
}
or set friendsCollectionView dataSource and delegate in your friends cell, where you init your collectionView.
If that shouldn't help you, check where and how you populate your myFriends dictionary.
Besides that, I'd recommend that you create a struct Friend:
struct Friend {
let ava: String
let firstName: String
let lastName: String
}
and change your var myFriends to
var myFriends: [Friend] = []
That would make it easier and safer to access the values for your friendsCollectionCell:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = friendsCollectionView...
let friend = MyFriends[indexPath.item]
let ava = friend.ava
...
return cell
}

How to populate data from class model to tableview

My data is coming in modal class named Menu by creating its object menus. Now How can i send the menu names to tableview to show in particular cell
var menus = [Menu]()
for (_, content) in json {
let menu = Menu(id: Int(content["id"].stringValue),
name: content["name"].string,
image: content["image"].string,
coupon: content["coupon"].int,
icon: content["icon"].string,
order: Int(content["order"].stringValue),
aname: content["name"].string,
options: Int(content["options"].stringValue),
subcategory:content["subcategory"].arrayObject)
menus.append(menu)
}
for menu in menus {
print(menu.name)
print(menu.id)
print(menu.subcategory)
}
print(menus.count)
Here All the data is saved in Menu class by the help of menus object.I have added the codes to show data to tableview. here i have created custom tableview and trying to populate it
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return menus.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Menucell", forIndexPath: indexPath)as! MENUTableViewCell
cell.Ordermenu.text = (" \(menus[indexPath.row])")///here its not fetching the value
return cell
}
Its not working . how the implementation should be ?
It shows the projectName.classname
updated after accepting answer
Try below line of code. Hope it will help you...
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Menucell", forIndexPath: indexPath)as! MENUTableViewCell
let menu : Menu = menus[indexPath.row]
cell.Ordermenu!.text = menu. name
return cell
}
Do you register the table cells? Try something like this...
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell: MENUTableViewCell! = tableView.dequeueReusableCellWithIdentifier("MENUTableViewCellIDENTIFIER") as? MENUTableViewCell
if cell == nil
{
let nib: UINib = UINib(nibName:"MENUTableViewCell", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier:"MENUTableViewCellIDENTIFIER")
cell = tableView.dequeueReusableCellWithIdentifier("MENUTableViewCellIDENTIFIER") as! CompactIncidentCellView
//cell.selectionStyle = UITableViewCellSelectionStyle.None
}
// work with cell here...
cell.Ordermenu.text = (" \(menus[indexPath.row])")
return cell
}

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!

wrong code for UITableview SWIFT

the main role is to display the playlists names in table view, but it show me word "name" in about 500 cells!
I can make a simple errors, because i only learning swift, and it is my first programming language
There is the code:
import UIKit
import MediaPlayer
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var tableView: UITableView!
var tableData = MPMediaQuery.playlistsQuery()
var songname: NSString = MPMediaPlaylistPropertyName
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.tableView.reloadData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tableData.items.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel.text = songname
return cell
}
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
println("Row \(indexPath.row) selected")
}
}
Your problem is that you're displaying MPMediaPlaylistPropertyName in the cell which is most likely just the constant string "name"
What you need to do is set the cell's textLabel with the actual name of the playlist which would look something like this in your cellForRowAtIndexPath method
Replace
cell.textLabel.text = songname
With
let playlist: MPMediaPlaylist = tableData.collections[indexPath.row] as MPMediaPlaylist
let playlistName = playlist.valueForProperty(MPMediaPlaylistPropertyName) as NSString
cell.textLabel.text = playlistName;
Also, you need to make sure you're getting the count from the collections of the tableData so in your number of rowsInSectionMethod change:
return self.tableData.items.count
to
return self.tableData.collections.count
For A bit more understanding, what we're doing in the cellForRowAtIndexPath now is:
Getting a specific MPMediaPlaylist item for that particular row
Getting the Name of the playlist and assigning it to a variable
Assigning that name to the cells textLabel
Let me know if you have any other questions
You have to cleanup the cell data since you are re-using the cells,
Right after line
var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
do
cell.textLabel.text = ""