ClipToBounds does not work when scrolling through cells

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

clipToBounds not working for editable cells

+3


source to share


4 answers


Add labels to the array.

Install hidden

in true

:



let labels = [firstLabel, secondLabel, etc.…]
for label in labels {
    label.hidden = true
}

      

+1


source


I think it is a bug with setEditing

overriding or ignoring clipsToBounds

during animation and editing.

Decision:

You must hide all items that should not appear when the table is "closed" and display them when the table is expanded.

1) Create a method UITableViewCell

to hide / show all required elements:

func hideAll(hide: Bool) {
        myLabel.hidden = hide
        myUISwitch.hidden = hide
}

      

2) Call the above method when you initialize your cells. Usually called somewhere inside a cell, on an initializer, or called on cellForRowAtIndexPath

. I check cell.bounds.height

to determine if a 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 the cell initializer) your method will be called when cells are created and every time the cell is expanded . But not when the cell shrinks (more on this ahead). So add the code to 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 only called in the cell you are scrolling and does not call any delegate methods like heightForRowAtIndexPath

so I think this is the best place to hide your view items.

Ok, that was the solution. Now WHY:

The real problem when you want to hide these cells is when you hide them. First you need to understand the loop that goes through tableViewCell

s quickly .

I am assuming that you are expanding / contracting cells by heightForRowAtIndexPath

. Which makes sense semantically. But let's say you have 3 cells (all expandable). I do println()

when called cellForRowAtIndexPath

, didSelectRowAtIndexPath

and heightForRowAtIndexPath

. In the following example, I knocked on the first line, then on the second, then on the third. Observe the results in 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 are didSelectRowAtIndexPath

, it heightForRowAtIndexPath

is called multiple times, looping until it is sure that it has all heights to the right. Meanwhile, it cellForRow

is called only on the selected cell.

So, if your cells are automatically reset when another cell is selected, you should understand that they do not run any code (like the hide elements method) when they collapse because cellForRowAtIndexPath

only the listening cell was called.

You could hide / hide inside your code heightForRow

, but this code gets called so many times that it really isn't optimal. The code should only be called once, when you need it. So the best solution IMO is to call it insideeditingStyleForRowAtIndexPath

+1


source


In the subclass, UITableViewCell

override the method willTransitionToState(state: UITableViewCellStateMask)

and set contentView.clipToBounds

it to true:

override func willTransitionToState(state: UITableViewCellStateMask) {
    super.willTransitionToState(state)

    contentView.clipsToBounds = true
}

      

From now on, it will properly close the child objects of the cell.

+1


source


try setting contentView's clipToBounds property to true. usually you shouldn't mess with the cell as a view.

Swift

cell.contentView.clipsToBounds = true

      

Obj-C

cell.contentView.clipsToBounds = YES

      

0


source







All Articles