Hide label when UITableView Cell is tapped - ios

I have a label within my cells that I would like to show/hide when tapped. I know that I have to get the index path of the cell that was tapped from within didSelectRowAtIndexPath. But I am unsure of how I then show/hide the label in that particular cell.
Am I able to show/hide it from within didSelectRowAtIndexPath, or is there a way to deal with it in cellForRowAtIndexPath and then update it?
I did some research into this but I really couldn't find a whole lot.
Here is all I have so far:
var selectedRowIndex: NSIndexPath = NSIndexPath(forRow: -1, inSection: 0)
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRowIndex = indexPath
}

Here is how you get to the cell from the index path:
let cell = tableView.cellForRowAtIndexPath(indexPath) as MyCustomCell
cell.myTextLabel.hidden = true
Also, depending on your needs, you might want to deselect the cell as well.
tableView.deselectRowAtIndexPath(indexPath)

Related

Swift - UITableview: How to make a tap on one cell cause change a label in another cell?

I have a UITableView, and I'd like a tap in cell X to cause the label text in cell Y to change from "Waiting..." to "Done". I'm pretty baffled as to how I should go about this. I've tried to do this using didSelectRowAtIndexPath , but seemingly I can only modify properties of the cell at the row tapped on.
Thanks!
Its quite easy to get a cell you need to change, but you have to know which row of your table it is:
class MyCell : UITableViewCell {
#IBOutlet weak var myLabel: UILabel!
}
class TableViewController: UITableViewController {
...
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let row = 7 //or what you set
let cellWhereIsTheLabel = tableView.cellForRow(at: IndexPath(row: row, section: 0)) as! MyCell
cellWhereIsTheLabel.myLabel.text = "Done"
}
...
}
A solution will be to update the datasource of your tableview.
When user taps on cell, didSelectRowAtIndexPath is called. In this function you can update datasource to provoke changes in other cells and then call reloadData to apply changes.
When you call reloadData tableView is updated by cellForRowAtIndexPath. This function uses your datasource to update cell.

Change image in UITableViewCell when selected

I want to change the image in a custom UITableViewCell, depending on whether it is selected or not.
So, when user selects a row, the image in two rows has to be changed (both the current selected and the one to be selected).
Calling reloadData, or reloadRowsAtIndexPaths from didSelectRowAtIndexPath doesn't work because it deselects the current selected row, which I don't want to happen.
Calling reloadData from willDeselectRowAtIndexPath and willSelectRowAtIndexPath also causes the same problem.
Anyone know a solution for this?
Did you try just programmatically selecting the row in cellForRowAtIndexPath based on a stored property indicating the selected row?
I would an approach where you still use reloadData, or reloadRowsAtIndexPaths from didSelectRowAtIndexPath but first save the selected row in a property so that you can manually set it as selected when the cell is redrawn.
For example:
var selectedRow:NSIndexPath? = nil
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRow = indexPath
tableView.reloadData() // or reload a specific row
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TableViewCellReuseIdentifier")
if (indexPath == selectedRow) {
cell!.selected = true
} else {
cell!.selected = false
}
}

Perform segue when cell with ID is selected

I am trying to create a segue happen when a cell has been selected. I have tired using cell.dequeueReusableCellWithIdentifier(""). However it is returning "nil" whilst unwrapping. I have set up the cells ID correctly and they match. Any help is greatly appreciated!!
if menuTableView.dequeueReusableCellWithIdentifier("") == "logout" {
print("logout")
performSegueWithIdentifier("logoutSegue", sender: self)
}
Thanks in advance
There is a UITableView delegate method for when a user selects a cell, this is good for knowing when a user has selected a cell, but we need to identify if it is the logout cell that has been pressed.
To identify the cell we'll be setting the tag property of the your logout cell.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == 0 {
//this is the indexPath row where we want our login cell to be showed
let loginCell = tableView.dequeueReusableCellWithIdentifier("login", forIndexPath: indexPath) as! LoginTableViewCell
//set the tag so when we select the cell we can see if the cell we have selected has a tag of 5
loginCell.tag = 5
return loginCell
}else {
//here goes our other cells, in this case they'll just be normal UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
return cell
}
}
In our cellForRowAtIndexPath delegate method we'll instantiate the loginTableViewCell in the first row and set its tag to 5, if the row isn't 0 we simply return our normal cell
So now we have a cell where the tag is 5 and all the other cells do not have a default tag property of 0, now, when the user selects a cell we can check for this method in the didSelectRowAtIndexPath delegate method of our table view.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath)!
if cell.tag == 5 {
//cell is login cell
//perform segue here
}
}
This delegate method gives us the table view and the indexPath of the selected cell. Now we call CellForRowAtIndexPath on the table view to get the cell that was selected. Now that we have the cell we can compare the cell's tag. If the tag is 5 the logout cell was selected so we can perform our segue there.

Why do UITableView actions only work on visible cells

I'm working with a UITableView which is a list of friends (I have 20 friends). I have, on top of those 20 friends cells, a unique cell in another section called "ALL FRIENDS" which allows me to select all my friends in one click.
When this "ALL FRIENDS" cell is selected, this code is called :
var index = 0
for friend in self.friendsList {
var indexPath = NSIndexPath(forRow: index, inSection: 1)
self.tableView.selectRowAtIndexPath(indexPath, animated: true, scrollPosition: UITableViewScrollPosition.None)
index += 1
}
Everything works fine for the visible cells. When a cell is selected the background color changes but this only works for visible cells.
Any ideas why ?
Because UITableView is dynamically displayed and invisible cells are not there.
UITableView basically dequeues a cell that's about to disappear and appends it where you're scrolling. To select all of the cells, you have to do it differently:
You'll have to set a global variable to true, let's say var allSelected = true.
Then call self.tableView.reloadData()
Which will be reflected in tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell by doing cell.selected = true.
That will ensure that all of the future displayed cells will be selected as well.
So Michal's answer is great, but I would like to give you an alternative: you can create that tableview without dequeuing and reusing cells, so the cells remain alive at all points.
You can do this by creating individual cells, and adding them to an array
var array = [UITableViewCell]
for friend in self.friendsList {
var cell = UITableViewCell()
// customize your cell however you want, or use custom nibs
array.append(cell)
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) {
return array[indexPath.row]
}

Swift - Selecting item in Collection View

I'm having a problem with selected items in a collection view.
Selected items change backgroundColor to blue, but it seems like the reusable cells are also affected.
my code looks like this:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
var cell = collectionView.cellForItemAtIndexPath(indexPath) as UICollectionViewCell?
cell?.contentView.backgroundColor = UIColor.blueColor()
func collectionView(collectionView: UICollectionView, didDeslectItemAtIndexPath indexPath: NSIndexPath) {
var cell = collectionView.cellForItemAtIndexPath(indexPath) as UICollectionViewCell?
cell?.contentView.backgroundColor = UIColor.blackColor()
}
func collectionView(collectionView: UIControllerView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell: boxCell = collectionView.dequeueReusableCellWithReuseIdentifier("demoCell", forIndexPath: indexPath) as boxCell
cell.cellTitle.text = name[indexPath.row]
}
When I run the application, the selection works, selecting another cell, deselects the other selected cells, but when I scroll, the reusable cells are also turning blue.
I am using a horizontal scroll direction with only 1 row and 4 cells per row.
Where did I go wrong? Anybody else have had this issue?
It's normal behavior - the reason for that is that the items are reused, and after reusing they go through cellForItemAtIndexPath where you are not setting background color, so they keep last one you ever set - in your case didSelect method.
You should create a NSSet where you will keep all selected NSIndexPath's and add / remove NSIndexPath to it when selecting / deselecting.
Setting background color logic should be done in cellForItemAtIndexPath - after you check if NSIndexPath is existing in your NSSet you set a desired color.
On selection you will have to also reload certain element, so it will call cellForItemAtIndexPath for the one you clicked.
Use the prepare for resue method in your cell class.It will work fine.
override func prepareForReuse()
{
self.backgroundColor = UIColor.lightGrayColor()
}

Resources