George
George

Reputation: 4029

iOS 7 UITableViewCell clips TEMPORARILY

I have been having the same issue as everybody else with UITableViewCell clipping to it's bounds. As someone else correctly pointed out , the cell's contentView has a new superview. So I did this:

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellIdentifier = @"HomeTableViewCell";
    ItemCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];

    if(!cell)
    {
        cell = [[ItemCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
       //add views here as subviews to cell.contentView. Set them tags and retrieve later.
    }

    cell.clipsToBounds  = FALSE;
    cell.layer.masksToBounds = FALSE;
    cell.contentView.clipsToBounds = FALSE;
    cell.contentView.layer.masksToBounds = FALSE;
    cell.contentView.superview.clipsToBounds = FALSE;
    cell.contentView.superview.layer.masksToBounds = FALSE;

    [self loadCell:cell inTable:tableView atIndexPath:indexPath];

    return cell;
}

loadCell: inTable: atIndexPath: retrieves the subviews of the cell by tag and loads the proper content. That's working fine. No other mentions of clipToBounds or layer.masksToBounds. BUT: When I reload the selected cell , it TEMPORARILY clips to bounds and then it hits the code above and gets it right. So for around 1-2 seconds I have the cells clipped. This is what's going on inside ItemCell. I just made this class to see what turns that clipToBounds property to TRUE.

@implementation ItemCell

- (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]))
    {
        [self addObserver:self forKeyPath:@"layer.masksToBounds"    options:NSKeyValueObservingOptionNew context:nil];
        [self addObserver:self forKeyPath:@"clipsToBounds"          options:NSKeyValueObservingOptionNew context:nil];
    }

    return self;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    NSNumber *nr = [change objectForKey:@"new"];
    if(nr.intValue)
    {
        self.clipsToBounds = FALSE;        // STAY FALSE!!
        self.layer.masksToBounds = FALSE;
    }
}

Even if I make them FALSE right when they turn to TRUE , I still get that gap between clipped/un-clipped. It's just smaller. That did not happen on iOS6. This is the stack trace when the clipsToBounds property turns to TRUE , you can see that CALayer setMasksToBounds gets called automatically:

enter image description here

Does anyone have any idea of any fix?? Thank you!

Upvotes: 5

Views: 1578

Answers (1)

djskinner
djskinner

Reputation: 8125

I seem to have fixed this problem in my code now. Firstly make sure everything is set up in Interface Builder with respect to clipping etc. Then all or some combination of the following code appears to be necessary:

In tableView:cellForRowAtIndexPath:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

    //ios7 hacks
    [cell.contentView.superview setClipsToBounds:NO];
    [cell.contentView setClipsToBounds:NO];
    [cell setClipsToBounds:NO];
    return cell;
}

In tableView:willDisplayCell:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    //ios 7 cell background fix
    [cell.contentView.superview setClipsToBounds:NO];
    [cell.contentView setClipsToBounds:NO];
    [cell setClipsToBounds:NO];
    [cell setBackgroundColor:[UIColor clearColor]];
    //ios 7 content clipping fix
    [cell.contentView.superview setClipsToBounds:NO];
    [cell.contentView setClipsToBounds:NO];
    [cell setClipsToBounds:NO];
}

Upvotes: 3

Related Questions