31

So I have code, which is sucessfully working on iOS 7.0 but not in 7.1. I have a simple tableview, with code:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 10;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 70.0;
}

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

    for (UIView *view in cell.contentView.subviews) {
        [view removeFromSuperview];
    }

    UILabel *label = [[UILabel alloc] init];
    label.text = [NSString string];

    for (NSInteger i = 0; i < 20; i++) {
        label.text = [label.text stringByAppendingString:@"label String "];
    }

    label.translatesAutoresizingMaskIntoConstraints = NO;
    label.numberOfLines = 0;
    label.lineBreakMode = NSLineBreakByWorldWrapping;
    //label.lineBreakMode = NSLineBreakByTruncatingTail; //I have tried this too
    [cell.contentView addSubview:label];

    NSDictionary *dict = NSDictionaryOfVariableBindings(label);
    [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-8-[label]-8-|" options:0 metrics:nil views:dict]];
    [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[label]" options:0 metrics:nil views:dict]];

    if (indexPath.row == 0) {
        label.textColor = [UIColor colorWithRed:1.0 green:0 blue:0 alpha:1.0];
    }
    else if (indexPath.row == 1) {
        label.textColor = [UIColor colorWithRed:0 green:1.0 blue:0 alpha:1.0];
    }
    else if (indexPath.row == 2) {
        label.textColor = [UIColor colorWithRed:0 green:0 blue:1.0 alpha:1.0];
    }
    else {
        label.textColor = [UIColor colorWithWhite:0.3 alpha:1.0];
    }

    cell.backgroundColor = [UIColor colorWithWhite:1.0 alpha:1.0];
    return cell;
}

I have 1section with 10rows. With each row reused I delete all subviews from contentView(I tried alloc-init UITableViewCell, but came with the same results).

On iOS 7.0, UILabel is displayed only in cell it belongs to. But in 7.1 UILabel continues displaying over another cells. What is interresting, that when I click on cell, it stop being overlaping by anothers, but only till I click on cell above. My question is, how to make it work on 7.1devices like on 7.0ones.

I tried both simulator and device and I took a look at iOS 7.1 API Diffs, but found nothing related to this.

Maybe it is issue of Auto Layout, that i have variable height of UILabel, but I need to do so. I want to have all text in UILabel, but display only part of UILabel, that can be displayed in a cell, which is default behavior in 7.0, but 7.1 changes this and I don't why why and how to deal with it.

This is dropbox folder for images with detail explanation: Folder with images

Update: I tried things like tese, but nothing worked for me.

cell.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 70);
cell.contentView.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 70);

cell.opaque = NO;
cell.contentView.opaque = NO;

cell.clearsContextBeforeDrawing = NO;
cell.contentView.clearsContextBeforeDrawing = NO;

cell.clipsToBounds = NO;
cell.contentView.clipsToBounds = NO;
asjj
  • 543
  • 5
  • 19
Matej Kosiarcik
  • 413
  • 2
  • 5
  • 6

7 Answers7

67

The issue has to do with the height of your cell. It isn't going to dynamically adjust that for you.

You'll probably notice that as you scroll and the view above goes out of view the overlapping text will disappear with it.

If you are wanting your text to clip at a certain height, then you need to set the number of lines, rather than setting it to 0 since that will let it continue forever.

The lineBreakMode won't take effect since it isn't stopped.

Optionally you could try to set clipping on the contentView to make sure all subviews stay inside.

Depending on the end result you want, you could do dynamic heights and change based on the content. There are a bunch of SO questions related to doing this.

Update - clipping the contentView

I'd have to try it out myself, but in lieu of that, here are a couple links related to clipping the contentView:

Looks like this works:

cell.clipsToBounds = YES;
Community
  • 1
  • 1
RyanJM
  • 7,028
  • 8
  • 60
  • 90
  • I noticed disappearing text while scrolling and when I scrolled up it looked just fine(like 7.0). I can set number of lines, but it takes only effect on UILabel, and when I have UIButton below UILabel, button continues overlapping cells. So I want more general solution. I simply want everything below visible area to not be visible => static row height 70. I am just confused why it happens only on iOS 7.1 Can you explain " It isn't going to dynamically adjust that for you." as I don't want it to be dynamic, I want cell to have static height 70. – Matej Kosiarcik Mar 12 '14 at 17:50
  • Right, if you want to have static height of 70 then you don't need dynamic heights. You'll just want to make sure the view clips the subviews. I'm not sure why 7.0 worked vs 7.1, I've had similar issues in previous versions. I'll add some links to my answer related to this. – RyanJM Mar 12 '14 at 17:53
  • After all I found solution: cell.clipsToBounds = YES; this solves my Problem and is well displayed on 7.0 and 7.1. Confused why I didn't find in Documentation that it is now necceary, if you wanna do it like me. As I am reading your comment now, I found that you mentioned it, so you can make answer an I'll mark it as accepted or I will make my ow. – Matej Kosiarcik Mar 12 '14 at 18:29
  • If you are building your cell in interface builder the Clip Subviews on the cell it self (top of the three) has the same effect.. – t0PPy Mar 19 '14 at 19:24
  • For me, this seem to be a problem with iOS 7.1 but not 7.0, that version works fine. But I guess the clipping is automatically turned on for 7.0. – Nate Hat Mar 23 '14 at 03:39
  • spent hour trying to resolve this issue. This finally resolved it. Thanks a lot Ryan – Pascal Jun 04 '18 at 18:24
7

Here is the Perfect solution of Overlapping content in Cells.

Just use below code in cellForRowAtIndexPath after allocating cell and before adding subviews.

for (id object in cell.contentView.subviews)
{
    [object removeFromSuperview];
}  

Actually the overlapping is occurring because whenever you scroll the tableview its allocating your added view again and again. So above code will solve your problem by removing the existing views from cell's contentView.

Now You can see the memory debug session after applying above code, your memory is stable this time.

Hope it'll help you.

Thanks !

Gaurav Singla
  • 2,271
  • 26
  • 43
  • This was not my problem. You are describing a situation where current view of cell0 overlaps previous view of cell0. But the problem was that current view of cell0 overlapped current view of cell1. Besides I do already have this code where you recommend (though now I would rather put it in prepareForReuse method). – Matej Kosiarcik Aug 17 '15 at 14:40
2

This is problem with recreating cell contents. Try with following code segment.

for(UIView *view in cell.contentView.subviews){  
        if ([view isKindOfClass:[UIView class]]) {  
            [view removeFromSuperview];   
        }
    }
Samitha K
  • 41
  • 2
  • when i write this code, the cells shows but the code doesn't remove the old cells i think. because i see the old values under the new cell – Esqarrouth Dec 08 '14 at 09:44
  • can you check this out: http://stackoverflow.com/questions/27355545/swift-reuse-cells-in-ios7-1-simulator-cells-are-hidden – Esqarrouth Dec 08 '14 at 10:07
2

@Gaurav your answer should be the accepted answer. Thanks!

for object in cell.contentView.subviews
            {
                object.removeFromSuperview();
            }
1

had similar behavior in iOS 8, using storyboard / IB.

fix was to add a Bottom Space to: Superview constraint from the bottom-most view to bottom of the prototype cell's Content View. The other views and constraints were all anchored from the top.

GraehamF
  • 1,971
  • 24
  • 24
0

Are you using storyboards? If so, select the table view controller in storyboards and uncheck the "Under bottom bars" You can also do this programmatically.

If your TVC inherits from a nav view controller or a tab view controller, you may need to uncheck this layout option on the parent view instead

TooManyEduardos
  • 4,206
  • 7
  • 35
  • 66
  • I tryed it but don't seem to do anything. Yes I am using Storyboards and my TableViewController belongs to NavigationController. I unchecked it on both, but nothing happened. – Matej Kosiarcik Mar 12 '14 at 17:36
  • Oh, another thing you could try is cleaning up the code inside of cellForRowAtIndexPath. I've noticed that if you put loops or some logic inside this code, things get kind of weird. So: move your for loop outside (make an array or something else to read from later), and possibly change the if/else statements for a switch statement and see if it helps – TooManyEduardos Mar 12 '14 at 17:45
  • Tried both but nothing helped. After all I found solution: cell.clipsToBounds = YES; this solves my Problem and is well displayed on 7.0 and 7.1. Confused why I didn't find in Documentation that it is now neccesary, if you wanna do it like me. I'll post answer, but must wait. – Matej Kosiarcik Mar 12 '14 at 18:30
  • This also worked for me, setting clipsToBounds = YES. Very frustrating. – ToddB Jun 05 '14 at 14:49
0

Re-checking all 4 constraints helps. While working with table view or collection view it's necessary to apply all four constraints (leading, trailing, top, bottom.)

Divyansh Jain
  • 373
  • 2
  • 5