5

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!

George
  • 4,029
  • 1
  • 23
  • 31
  • 1
    I think I'm having a similar problem. – djskinner Nov 10 '13 at 17:52
  • Please let me know if you find any solution. I got nothing so far , I have a lot of projects to work on and that small glitch was declared 'acceptable' by the manager so I haven't worked on it anymore. But I'm still curious. – George Nov 11 '13 at 08:53

1 Answers1

3

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];
}
djskinner
  • 8,035
  • 4
  • 49
  • 72
  • Thank you for the response. I tried using 'willDisplayCell' really had my hopes up for this but unfortunately it didn't work either. – George Dec 10 '13 at 11:35
  • One other thing that might apply is that I ended up turning animations off - just using `reloadData` rather then `beginUpdates` and `endUpdates`. Not an ideal solution, obviously! – djskinner Dec 11 '13 at 12:32
  • I'm reloading 2 cells . The previously selected one and the newly selected one. Begin and end updates are used when you want to do more operations and animate them at once ...like delete one row , update another and insert another , versus animating each thing. I'll try using 'UITableViewCellAnimationNone' but AFAIK there's still some animation involved there (saw this in a WWDC video about tables.) Thanks! – George Dec 12 '13 at 08:35