I have a custom cell with several labels hidden by default (the user sees all content when clicking on the cell). I'm changing the height of the cell and cell.clipToBounds = true to hide the labels. But this doesn't work for editable cells. When I start swiping the cell to left, the hidden content appears. I noticed that it works if I first expand the cell, collapse and the swipe, but stops working if I swipe another cell. Any suggestions how to hide it when the cell is swiped?

Add the labels to an array.
Set hidden to true:
let labels = [firstLabel, secondLabel, etc.…]
for label in labels {
label.hidden = true
}
I think that is a bug with the setEditing overriding or ignoring clipsToBounds during the animation and edit.
The solution:
You should hide all the elements which should not appear when the table is "closed", and unhide them when the table is expanded.
1) Create a UITableViewCell method to hide/unhide all elements you need:
func hideAll(hide: Bool) {
myLabel.hidden = hide
myUISwitch.hidden = hide
}
2) Call the above method when you initialize your cells. Usually will be called somewhere inside the cell, on an initializer, or will be called on cellForRowAtIndexPath. I check for the cell.bounds.height to determine if the cell is expanded or not:
//cell init code
//I'm calling this method from inside the cell, so I use self here.
//If you're calling this method from your controller you should
//target the cell with cell.bounds.height, as well as targeting the
//cell to call the method: cell.hideAll(Bool)
var hidden = (self.bounds.height < 80) //change this number depending on your collapsed and expanded cell heights
hideAll(hidden)
3) At this point (if the above method was called inside cellForRowAtIndexPath or on a cell initializer) your method will be called when the cells are created and every time the cell expands. But not when the cell contracts (more on this ahead). So add some code in your editingStyleForRowAtIndexPath:
override func tableView(tableView: UITableView,
editingStyleForRowAtIndexPath indexPath: NSIndexPath)
-> UITableViewCellEditingStyle{
if let cell = tableView.cellForRowAtIndexPath(indexPath) as? CustomTableViewCell {
cell.hideAll(cell.bounds.height < 80) //calls hideAll with a Bool argument, depending on height of cell
}
return .Delete
}
editingStyleForRowAtIndexPath is called only on the cell you swipe, and doesn't call any of the delegate methods such as heightForRowAtIndexPath, so I believe this is the best place to hide your view items.
Ok, that was the solution. Now the WHY:
The true problem when you want to hide these cells is when to hide them. First you have to understand the cycle that swift goes through with tableViewCells.
I'm assuming you're expanding/contracting the cells on the heightForRowAtIndexPath. Which semantically makes total sense. But let's suppose you have 3 cells (all expandable). I'm doing a println() whenever cellForRowAtIndexPath, didSelectRowAtIndexPath and heightForRowAtIndexPath are called. In the following example, I tapped on the first row, then on the second, then on the third. Observe the results on the console:
>>>> called didSelectRow at index 0
???? called heightForRow at index 0
???? called heightForRow at index 1
???? called heightForRow at index 2
???? called heightForRow at index 0
==== called cellForRow at index 0
???? called heightForRow at index 0
>>>> called didSelectRow at index 1
???? called heightForRow at index 0
???? called heightForRow at index 1
???? called heightForRow at index 2
???? called heightForRow at index 1
==== called cellForRow at index 1
???? called heightForRow at index 1
>>>> called didSelectRow at index 2
???? called heightForRow at index 0
???? called heightForRow at index 1
???? called heightForRow at index 2
???? called heightForRow at index 2
==== called cellForRow at index 2
???? called heightForRow at index 2
As you can see, when you didSelectRowAtIndexPath, heightForRowAtIndexPath is called multiple times, cyclically, until swift is sure it has all the heights right. Meanwhile, cellForRow is called only on the cell you selected.
So if your cells auto-collapse when you select another cell, you have to realize they're not running any code (such as the method to hide elements) when they collapse, because cellForRowAtIndexPath was called only on the tapped cell.
You could hide/unhide inside your heightForRow code, but that code is called so many times that it's really not optimal. Code should be called only once when you need it. So the best solution IMO is to call it inside the editingStyleForRowAtIndexPath
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With