0

Most of the time, when my app is working the way it should, my Table View items look like this:

enter image description here

But every so often a cell (on initial load) looks likes this:

enter image description here

As you can see the image has resized, the 'published By' label has resized.

Why would this happen? The same code/storyboard should affect all the cells the same way? Why are some not doing what they are told?

If it helps, when a cell loads the wrong way, all I have to do is scroll up, and back down again, and the problem is fixed !!

This means that there clearly isn't a problem with the image or the amount of text, is it just the iPhone acting up?

Thanks for any help !

Greg Peckory
  • 7,700
  • 21
  • 67
  • 114
  • Have you use auto layout? – Nimit Parekh Jul 17 '15 at 10:53
  • Are the constraints ok, no warnings? Can they cope with size changes when the data is put into the cell? – Eiko Jul 17 '15 at 10:55
  • I think the constraints are OK. I am using Auto Layout. Why is it that scrolling down and back up fixes the issue. Wouldn't this imply that there is no problem with the data itself? – Greg Peckory Jul 17 '15 at 10:57
  • @GregoryPeck I suppose, it happens because of load order of an image, do you load it from the internet? Or is it in your resources? – Nik Yekimov Jul 17 '15 at 10:59
  • @nyekimov I load the images asynchronously from the internet, yes! – Greg Peckory Jul 17 '15 at 11:33
  • @GregoryPeck then the issue with that, your image is loaded after constraints are calculated, I suppose, sometimes load applies very fast. You should check constraints, when imageView is empty or force cell to redraw after image finish loading. – Nik Yekimov Jul 17 '15 at 12:02
  • @nyekimov Well I have a placeholder image set before the image loads, this is there by default... and thanks for the help ! – Greg Peckory Jul 17 '15 at 12:07
  • @nyekimov how would you force cell to redraw? – Greg Peckory Jul 17 '15 at 12:15
  • @nyekimov I tried this answer for forcing cell to redraw... no luck : http://stackoverflow.com/a/27045128/1449637 – Greg Peckory Jul 17 '15 at 12:53
  • Maybe we should have a look at the methods that fill the cell when the data arrives (and the initial filling with dummy data). – Eiko Jul 17 '15 at 14:10
  • @Eiko I basically replace the text in the labels with downloaded data. The images are updated asynchronously. Is it a problem that I am using constraints but I still change the row heights programatically and dynamically. There is a lot of code to show – Greg Peckory Jul 17 '15 at 14:37
  • @GregoryPeck Changing cell sizes has always been a non-trivial task. Make sure that your constraints work with all sizes, and you might need to call 'setNeedsUpdateConstraints' and 'setNeedsLayout' etc. This link might be worth a read: http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout – Eiko Jul 17 '15 at 14:58

2 Answers2

1

I think its cell dequeue issue. Your cell could not calculate proper height for cell. If you are using autolayout try the following code. hope it will works for you.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static YOUR_TABLEVIEW_CELL *sizingCell = nil;
    static NSString *CellIdentifier=@"YOUR_TABLEVIEW_CELL_IDENTIFIER";
    sizingCell =[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (sizingCell==nil)
    {
        sizingCell=[[YOUR_TABLEVIEW_CELL alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    [self configureFareIssueCell:sizingCell atIndexPath:indexPath];
    return [self calculateHeightForConfiguredSizingCell:sizingCell];
}

//assign all the lables & images here
- (void)configureFareIssueCell:(YOUR_TABLEVIEW_CELL* )cell atIndexPath:(NSIndexPath *)indexPath
{
    //e.g 
    cell.lbl.text=@"YOUR_TEXT";
    cell.imageView.image=[UIImage imageNamed:@"NAME_OF_YOUR_IMAGE"];
} 

- (CGFloat)calculateHeightForConfiguredSizingCell:(YOUR_TABLEVIEW_CELL *)sizingCell
{
    CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
    return size.height + 1.0f; // Add 1.0f for the cell separator height
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier=@"YOUR_TABLEVIEW_CELL_IDENTIFIER";
    YOUR_TABLEVIEW_CELL   *cell =[tableView dequeueReusableCellWithIdentifier:@"YOUR_TABLEVIEW_CELL_IDENTIFIER"];
    if (cell==nil)
    {
        cell=[[YOUR_TABLEVIEW_CELL alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    [self configureFareIssueCell:cell atIndexPath:indexPath];

    return cell;
}
Eiko
  • 25,601
  • 15
  • 56
  • 71
swapnali patil
  • 304
  • 2
  • 17
  • Is there any hint in the question that might indicate your answer is related to it? (Please don't use typographic quotation marks in code snippets) – Eiko Jul 17 '15 at 14:09
  • Also, (as it says in the tag), I'm working with swift, and I find it very difficult to understand objective-c since Ive never used it. Any chance you could explain with references to swift code. Thanks! – Greg Peckory Jul 17 '15 at 14:31
0

Do you use layer mask for creating rounded image? If yes, you see this strange behavior because layer mask was created before UITableView assign proper frame for cell, so layer mask will have incorrect frame.

Pr0Ger
  • 528
  • 6
  • 15
  • Place this code to `layoutSubviews` method inside your table view cell class, so mask size will have a correct size. – Pr0Ger Jul 18 '15 at 19:17
  • If this would fix my problem I'd be so so grateful ! So, inside the `layoutSubviews` function do I loop through all the cells in the TableView and run the above code. Or does layoutSubviews apply to each individual cell already? – Greg Peckory Jul 20 '15 at 08:52
  • Is the `layoutSubviews` method specific to table views? – Greg Peckory Jul 20 '15 at 09:47
  • No, every `UIView` instance have `layoutSubviews` method. It will be called when view frame has been changed. In this case, you should override this method in table view cell class. – Pr0Ger Jul 20 '15 at 16:40
  • Sorry, you're probably getting impatient. I've never actually used table view cell classes, I just defined everything in the `cellForRowAtIndexPath`. Is it a necessity to create the cell classes? And if so, do I get rid of the `cellForRowAtIndexPath`? – Greg Peckory Jul 20 '15 at 18:57
  • Creating subview inside `cellForRowAtIndexPath:` is really bad for performance, because it constantly recreates views when scrolling. So yes, create custom class for your cell, create all subviews inside `initWithStyle:reuseIdentifier:` method (or use xib/storyboard if you want), and create proper mask for image inside `layoutSubviews` method. And then you can use `dequeueReusableCellWithIdentifier` for creating cell inside `cellForRowAtIndexPath` method. And no, you can't use `UITableView` without `cellForRowAtIndexPath` method – Pr0Ger Jul 21 '15 at 17:07