How to store a hidden string with a UITableViewCell? - xcode

I want to attach information (a string) to each UITableViewCell when populating TableView with UITableViewCells. I don't want it to be visible- I just need to access this string when the row/cell is selected. What is the best way to do this?

Your best choice is probably to subclass UITableViewCell and add a string property. This can then be assigned either as a constant, or when setting up your cells in cellForRowAtIndexPath:.
class CustomCell: UITableViewCell {
var customString = "Default"
}
--------
func cellForRow(atIndexPath indexPath: IndexPath) -> UITableViewCell {
guard let cell: CustomCell = tableView.dequeueReusableCell(withReuseIdentifier: "identifier", indexPath: indexPath) as? CustomCell else {
return UITableViewCell()
}
cell.customString = "String"
return cell
}
func didSelectRow(atIndexPath indexPath: IndexPath) {
guard let cell: CustomCell = tableView.cellForRow(atIndexPath: indexPath) as? CustomCell else {
return
}
let stringFromCell = cell.customString
}
The above has not been compiled, so may not work word for word, but you get the principle.

Add a property selected to your model.
In cellForRow show/hide the string depending on the state of selected.
In didSelectRow toggle selected in the model and reload the row.

Related

Xcode error: 'Cannot assign to value: function call returns immutable value' in table views

I am confused as I am defining content of rows in a table view by a dictionary, but when ever I try to add it, it shows me an error.
var places = [[String: Any]]()
class TableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
if places.count == 0 {
places.append(["name":"Taj Mahal", "lat": "27.175277", "lon": "78.042128"])
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
cell.textLabel?.text = places[indexPath.row]["name"]
return cell
}
the error is in the part where I define:
cell.textlabel?.text = places[indexPath.row]["name"]
It should be:
places[indexPath.row]["name"] as! String
As the type is Any and you need to specify it as String, since label expects Strings.

getting the index path of a cell inside UITableViewCell in swift

could anyone tell me how to get the index of a cell inside its class which is uitableViewCell more specifically , inside an action function of UISwitch .
I did the following..
var cell = sender.superview?.superview as UITableViewCell
var table: UITableView = cell.superview as UITableView
let indexPath = table.indexPathForCell(cell)
but then it crashes.
what is the solution ?
Try this:
Assuming you have a UISwitch *cellSwitch object in cell custom class
In cellForRowAtIndexPath:
cell.cellSwitch.tag = indexPath.row
In IBAction for this switch:
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
You don't want to know the index path of the cell inside of the cell. The index path is an implementation detail of the UITableViewController. The cell should be an independent object.
What you really want to do is to assign an action to run when your switch is changed.
class MySwitchCell: UITableViewCell {
#IBOutlet weak var switchCellLabel: UILabel!
#IBOutlet weak var mySwitch: UISwitch!
//Declare an action to be run
var action: ((sender: UISwitch) -> Void)?
//then run it
#IBAction func switchAction(sender: UISwitch) {
action?(sender: sender)
}
}
Then give the action something to do when you configure the cell.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("SwitchCell", forIndexPath: indexPath) as! MySwitchCell
cell.switchCellLabel.text = items[indexPath.row]
cell.mySwitch.on = NSUserDefaults.standardUserDefaults().boolForKey(items[indexPath.row])
cell.action = { [weak self] sender in
if let tableViewController = self {
NSUserDefaults.standardUserDefaults().setBool(sender.on, forKey: tableViewController.items[indexPath.row]) }
}
return cell
}
For example this one sets a bool in the NSUserDefaults based on the state of that switch.
You can checkout the whole sample project from https://github.com/regnerjr/SimpleCellSwitchAction

Swift 1.2 - List type undeclared

In my TableViewController i have this line of code
override func tableView(tableView: UITableView,cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
In this block i try to get a list of objects
let list = frc.objectAtIndexPath(indexPath) as! List
But i get this warning:
Use of undeclared type "List"
Anybody knows how to deal with it?
This is the full code:
var frc: NSFetchedResultsController = NSFetchedResultsController()
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell",
forIndexPath: indexPath) as! UITableViewCell
// Configure the cell...
let list = frc.objectAtIndexPath(indexPath) as! list
cell.textLabel?.text = list.name
cell.detailTextLabel?.text = list.url
return cell
}
Any help is welcome!!
Greetings and Thanks
In the tutorial, Jason creates an entity called "List" in his Data Model file and then creates a class called List.
The following link starts the video just after he creates this file.
https://youtu.be/GeM7Zw12wbM?t=5m30s
You may have named your entity differently.
I named mine Record, since I'm storing records.
So my code will look like the following:
var frc: NSFetchedResultsController = NSFetchedResultsController()
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell",
forIndexPath: indexPath) as! UITableViewCell
// Configure the cell...
// ALL occurrences of "list" are instead "record"
// ALL occurrences of "List" are instead "Record"
let record = frc.objectAtIndexPath(indexPath) as! Record
cell.textLabel?.text = record.name
cell.detailTextLabel?.text = record.url
return cell
}

UITableView with 3 custom cells but 1 different

I have a TableView and I have created custom cells for that TableView with images, labels..etc, But I want one cell to be different than the others with It's own content ( cells will get their data from a backend).
So how to create 2 different types of cells in the same TableView, and how to arrange them, for example put 1 type of cell between 2 others ?
Edit: My UITableView Class:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let myCell: CellTableViewCell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! CellTableViewCell
let otherCell: OtherCellTableViewCell = tableView.dequeueReusableCellWithIdentifier("otherCell", forIndexPath: indexPath) as! OtherCellTableViewCell
// Configure the cell...
return myCell
}
If you're using a storyboard, just drag another UITableViewCell into the table view to be used as a prototype. Give it a unique and subclass (if necessary). In -tableView:cellForRowAtIndexPath: dequeue either the cell you're currently dequeueing, or this new one.
If you're not using a storyboard you'll need to either
-registerClass:forHeaderFooterViewReuseIdentifier: or
-registerNib:forHeaderFooterViewReuseIdentifier: to make your other cell style available to the table view.
Here's a modified version of your code that should work:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if condition {
let myCell: CellTableViewCell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath) as! CellTableViewCell
// Configure the cell...
return myCell
}
else {
let otherCell: OtherCellTableViewCell = tableView.dequeueReusableCellWithIdentifier("otherCell", forIndexPath: indexPath) as! OtherCellTableViewCell
// Configure the cell...
return otherCell
}
}

Xcode - cellForRowAtIndexpath - initialising cell

What's the difference between this:
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
And this:
var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
They both seem t work fine for me.
PS: I know this seems to be an amateur question but i'm beginner in Xcode, so no reason to be a smug.
When you write :
var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
You are initializing a new cell using its constructor.
And when you write :
var cell = self.tableView.dequeueReusableCellWithIdentifier("cell")
You are dequeuing a cell, so you are assuming your cell with the identifier cell has been already registered in the tableView.
Typically, if the cell was designed in Interface Builder and set as a prototype cell or if you have registered your cell for reuse using the method self.tableView.registerClass(MyCell.classForCoder(), forCellReuseIdentifier: "cell") you won't need to use the constructor because it is already initialized in the tableView.
But if your cell is designed programmatically such as creating UILabel, UIImage or whatever components, you will have to use the constructor instead, and then use the dequeue method.
So, if you have to use the constructor (because you're initializing everything by code) your code will look like this :
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
}
cell.cellLabel.text = "Hello world"
cell.cellImage.image = UIImage(named: "funny_cat.jpg")
return cell
}
But if your cell was registered for reuse or if it is a prototype cell you will just have to use
override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.cellLabel.text = "Hello world"
cell.cellImage.image = UIImage(named: "funny_cat.jpg")
return cell
}
I think the best place to look how tableview work, you should look the official documentation here : Table View Programming Guide for iOS

Resources