I am trying the get the Text in Label ID nameLabel when i click on the cell
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
NSLog("You selected cell number: \(indexPath.row)!")
// get text in label nameLabel
}
With MVC you get this information from the model, not from the view.
Since you have the indexPath of the cell, you can use that to get the object that the cell is displaying from the data source.
I think you should have a data Model to keep all the data of your cells. When you select a cell, this function will be called
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// indexPath is the cell you selected
// you can use indexPath.row to get the data from the data Model
}
Your Data Model may be a dic or an Array / set and so on.
Assuming that you have a custom cell (In the code snippet I assumed that its class name is MyCustomCell), containing a label (In the code snippet I assumed that the label's name is nameLabel), it should something like:
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
NSLog("You selected cell number: \(indexPath.row)!")
// get text in label nameLabel
let selectedCell = tableView.cellForRowAtIndexPath(indexPath) as! MyCustomCell
// here is the text of the label
let string = selectedCell.nameLabel.text
}
Related
I would like the selected cell to be pinned to the Tableview top and stay there while scrolling like section header when .plain style is used but for cell.
I don't know how to approach the problem. I know that the code should be placed at didSelectRowAt.
If your tableView cells are static, and you want the selected cell to be displayed at the top, You should try:
optional func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedRow = tableView.cellForRow(at: indexPath) as! yourTableViewCell // this wont apply if your cells are static
let firstVisibleIndexPath = tableView.indexPathsForVisibleRows.first
tableView.moveRow(at: indexPath, to: firstVisibleIndexPath)
}
I am very confused on the reuse of the cells.
I have a table, each cell is a cell with a switch on it. If I toggle a switch I set the background color of that cell to a different color. However every time I scroll these changes don't persist.
I am subclassing UITalbeViewCell to create my own custom cell. Each cell has a different identifier. However when I scroll through the table, whatever changes I made to the cell still doesn't save. I've read similar questions but none of them worked.. Some suggested subclass which I did, some suggested use different identifier which I also did...
Here is the code of my tableview.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let key = Array(dataSource[indexPath.section].keys)[indexPath.row]
let cell = CellWithSwitch.init(style: .subtitle, reuseIdentifier: key)
cell.awakeFromNib()
let val = Array(dataSource[indexPath.section].values)[indexPath.row]
cell.switchView?.addTarget(self, action: #selector(self.switchChanged(_:)), for: .valueChanged)
if let index = key.firstIndex(of: "."){
cell.textLabel?.text = String(key.suffix(from: key.index(index, offsetBy: 1)))
}else{
cell.textLabel?.text = key;
}
cell.switchView?.setOn(val, animated: true)
return cell
}
You can change array value in switchChange action
lets i take array for switch as below:
var arrSwitch = [false,false,false,false,false,false,false,false,false,false]
Below is my cellForRowAt Method
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "customCell") as! customCell
cell. switchView.setOn(self.arrSwitch[indexPath.row], animated: false)
cell. switchView.tag = indexPath.row
cell. switchView.addTarget(self, action: #selector(self.onSwitchTap(_:)), for: .valueChanged)
return cell
}
Here is my onSwitchTap Action
#IBAction func onSwitchTap(_ sender: UISwitch) {
self.arrSwitch[sender.tag] = !self.arrSwitch[sender.tag]
}
Now on scroll it will persist last changes you have done.
I am making an app that requires the user to tap on multiple cells in order to select them. when they tap on a cell, a .Checkmark accessory item will appear. For some reason though whenever I try and get to that VC the app crashes and I get the following error messages on line 8(if !checked[indexPath.row]):
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell: InstrumentTableCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? InstrumentTableCell
cell.configurateTheCell(recipies[indexPath.row])
if !checked[indexPath.row] {
cell.accessoryType = .None
} else if checked[indexPath.row] {
cell.accessoryType = .Checkmark
}
return cell
}
and this is my working checked method:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
tableView.deselectRowAtIndexPath(indexPath, animated: true)
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
if cell.accessoryType == .Checkmark {
cell.accessoryType = .None
checked[indexPath.row] = false
} else {
cell.accessoryType = .Checkmark
checked[indexPath.row] = true
}
}
}
Your problem is that you only store items in your checked array when tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) is called. However, that method is only called when you actually select a row.
tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) on the other hand is called each and every time you need to render a new table cell.
So when you in cellForRowAtIndexPath asks:
if !checked[indexPath.row]
then you can not be sure that checked actually contains anything. For instance the first time you start rendering your cells, your checked array does not contain any values and therefore it crashes when you ask it for a value on a position that it does not have a value for.
One solution could be to initialize your checked array to contain all false values. I'm guessing you have some model array called recipies so you could do something like:
for (index, _) in recipies.enumerate() {
checked.append(false)
}
Or as #AaronBrager suggests in the comments below (which is way prettier :))
checked = Array(count:recipies.count, repeatedValue:false)
that way you are sure that your checked array is properly initialized with the same number of elements as you have recipies.
Another option could be to let the individual elements in recipies know whether or not they are checked.
Hope this makes sense and helps you.
I have an UIImageView in a custom cell (#IBOutlet var imageSquadra: UIImageView!) and in the TableViewController I initialize this imageView:
let squadra = DataManager.sharedInstance.arrayCori[indexPath.row]
cell.imageSquadra.image = squadra.sfondo1
Now I need to change the image touching up inside the cell with an other image, and return to the previous image touching up into an other cell.
Is it hard to do?
EDIT: or if was easier, would be fine apply a CAFilter like a shadow to the image.
On your tableview set multiple selection to NO:
tableView.allowsMultipleSelection = false
Then you want something like this on your TableViewController
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Store which indexPath has been selected in a global variable
tableView.reloadData()
}
func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {
tableView.reloadData()
}
In your cellForRow method you want something like...
cell.useSelectedImage(indexPath == storedIndexPath)
And finally in your custom cell class you want to add a method that does similar to this
func useSelectedImage(bool:useSelected)
{
self.myImage = useSelected ? "selectedImage" : "unselectedImage"
}
My Swift is a bit rusty... but you should be able to get the general idea from what I've done here
I have created a UITableView Containing 10 cells, each of which have a UIImageView attached to them using auto-layout
The table is populated in my BackTableViewController by the code:
TableArray = ["Home Page", "Membership Card", "Recent News", "Fitness Schedule", "Training Log", "Pool Lap Calculator", "Martial Arts Schedule", "Pool Schedule", "Comments", "Acknowledgements"]
The issue is that none of these images appear in the table until the cell is selected while run. I am out of ideas as to why this is... anyone?
Thanks
Edit: BackTableViewController
import UIKit
class BackTableViewController: UITableViewController {
var TableArray = [String]()
var ImageArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
TableArray = ["Home Page", "Membership Card", "Recent News", "Fitness Schedule", "Training Log", "Pool Lap Calculator", "Martial Arts Schedule", "Pool Schedule", "Comments", "Acknowledgements"]
ImageArray = ["home-50.png","credit_card-50.png","info-50.png","math-50.png","news-50.png","report_card-50.png","weightlift-50.png"]
// Do any additional setup after loading the view.
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TableArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier(TableArray[indexPath.row], forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = TableArray[indexPath.row]
return cell
}
}
You only need one prototype cell with a reuse identifier. The clue is in the name "prototype". Think of them as blueprints all cells are based off.
In your view controller class (which should be a UITableViewDelegate if it is a UITableViewContoller) you specify the number of rows with this method:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return yourArray.count
}
This is the method that takes care of displaying the right info in the right row of the table.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//We create a cell from our prototype that we gave an identifier to in our storyborad.
let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell") as! UITableViewCell
//Create a single instance of an item from our items array. we use the indexpath.row that was passed into this method as the index for the array.
let item = yourArray[indexPath.row]
//You can go into your array and get the right info out regarding this row by using the indexPath.row
cell.textLabel?.text = item
cell.imageView?.image = UIImage(named: item)
//Finally this method returns the correctly configured cell fro the tableview to display.
return cell
}
Hope this helps.
Try giving "Center x" constraint instead of leading space for the image view, and you should give it width and height constraint also.
You need to set your cell identifier using Interface Builder in the Attributes Inspector:
Then in your cellForRowAtIndexPath you need to pass the cell identifier as you set before, something like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// set the identifier cell, not TableArray[indexPath.row]
var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = TableArray[indexPath.row]
return cell
}
I hope this help you.