title: Why is my custom UITableViewCell width incorrect on initial load?
body: <p>There are 2 stipulations to this issue. It CANNOT be solved by either a) </p>
  
  <pre><code>- (void)viewDidAppear:(BOOL)animated { 
      ...
      [self.tableView reloadData]
  }
  </code></pre>
  
  <p>or b)</p>
  
  <pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  ...
      [cell layoutIfNeeded];
  }
  </code></pre>
  
  <p>a) A does not work as the data for the cells is not present when viewDidAppear is called. The data is fetched asynchronously from the server in a background thread and takes some time to retrieve. ALSO, <code>[self.tableView reloadData]</code> in the completion block of this call does not work either. (Yes, that reloadData statement is doing it's job and being executed on the main thread)</p>
  
  <p>b) This should never need to be called from cellForRowAtIndexPath, and is a warning sign of a bigger issue. While calling <code>[cell layoutIfNeeded]</code> is solving the width issue, it's coming at a massive cost. 6-10ms per call. cellForRowAtIndexPath must stay under 13.67ms (1/60fps) otherwise you'll get performance issue. This call is causing massive performance issues, and is not the proper solution either.</p>
  
  <p>Now, on to the issue:</p>
  
  <p>1) As you can see in my nib here [<a href="http://i.imgur.com/oa8xZvB.png]" rel="nofollow">http://i.imgur.com/oa8xZvB.png]</a>, my Cell, and ContentView both have widths of 321.</p>
  
  <p>2) I have the following code cellForRowAtIndexPath</p>
  
  <pre><code>NSLog(@"TableView     Width: %f", self.tableView.frame.size.width);
  NSLog(@" ContentView   Width: %f", cell.contentView.frame.size.width);
  NSLog(@"  ContainerView Width: %f", cell.containerView.frame.size.width);
  NSLog(@"   CardView      Width: %f", cell.cardView.frame.size.width);
  </code></pre>
  
  <p>3) After initial load, these are the results/output are scrolling all the way down and back up again 3 times.</p>
  
  <pre><code>2015-04-28 11:24:10.026 Roto Forum[82016:683164] TableView     Width: 375.000000
  2015-04-28 11:24:10.026 Roto Forum[82016:683164]  ContentView   Width: 321.000000
  2015-04-28 11:24:10.027 Roto Forum[82016:683164]   ContainerView Width: 345.000000
  2015-04-28 11:24:10.027 Roto Forum[82016:683164]    CardView      Width: 305.000000
  ...
  ... 3 more sets exactly like these removed for brevity ...
  ...
  2015-04-28 11:24:12.867 Roto Forum[82016:683164]  ContentView   Width: 321.000000
  2015-04-28 11:24:12.867 Roto Forum[82016:683164]   ContainerView Width: 345.000000
  2015-04-28 11:24:12.867 Roto Forum[82016:683164]    CardView      Width: 305.000000
  2015-04-28 11:24:12.901 Roto Forum[82016:683164] TableView     Width: 375.000000
  2015-04-28 11:24:12.901 Roto Forum[82016:683164]  ContentView   Width: 375.000000
  2015-04-28 11:24:12.901 Roto Forum[82016:683164]   ContainerView Width: 383.000000
  2015-04-28 11:24:12.901 Roto Forum[82016:683164]    CardView      Width: 343.000000
  ...
  ... 37 more sets exactly like these removed for brevity ...
  ...
  2015-04-28 11:24:20.716 Roto Forum[82016:683164] TableView     Width: 375.000000
  2015-04-28 11:24:20.716 Roto Forum[82016:683164]  ContentView   Width: 375.000000
  2015-04-28 11:24:20.716 Roto Forum[82016:683164]   ContainerView Width: 383.000000
  2015-04-28 11:24:20.716 Roto Forum[82016:683164]    CardView      Width: 343.000000
  </code></pre>
  
  <p>The first 5 sets of this code output look like this...</p>
  
  <pre><code>2015-04-28 11:24:10.026 Roto Forum[82016:683164] TableView     Width: 375.000000
  2015-04-28 11:24:10.026 Roto Forum[82016:683164]  ContentView   Width: 321.000000
  2015-04-28 11:24:10.027 Roto Forum[82016:683164]   ContainerView Width: 345.000000
  2015-04-28 11:24:10.027 Roto Forum[82016:683164]    CardView      Width: 305.000000
  </code></pre>
  
  <p>And the last 40 look like this...</p>
  
  <pre><code>2015-04-28 11:24:20.716 Roto Forum[82016:683164] TableView     Width: 375.000000
  2015-04-28 11:24:20.716 Roto Forum[82016:683164]  ContentView   Width: 375.000000
  2015-04-28 11:24:20.716 Roto Forum[82016:683164]   ContainerView Width: 383.000000
  2015-04-28 11:24:20.716 Roto Forum[82016:683164]    CardView      Width: 343.000000
  </code></pre>
  
  <p>The initially loaded cells have ContentView/ContainerView/CardView width values of 321/345/305 while all subsequent times that or any other cell is loaded it has width values of 375/383/343. What gives?</p>
  
  <p>These are the one that are loading initially as they are viewable on the table view from the get go. The last 40 is what I get every time scrolling up and down the table view. Why do I get these incorrect width's on initial load?</p>
  
  <p><strong>=========================== EDIT: ===========================</strong> </p>
  
  <p>Adding some code as requested in the first comment</p>
  
  <p>heightForRowAtIndexPath: Not implemented as this is an iOS8 Self Sizing Cell.</p>
  
  <p>cellForRowAtIndexPath:</p>
  
  <pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  {
      static NSString *cellIdentifier = @"MyCardCell";
      MyCardCellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
  
      Question *question = [self.questions objectAtIndex:indexPath.row];
  
      cell.title.text = question.questionTitle;
      cell.subtitle.text = question.questionText;
      cell.username.text = question.userName;
  
      NSLog(@"TableView     Width: %f", self.tableView.frame.size.width);
      NSLog(@" ContentView   Width: %f", cell.contentView.frame.size.width);
      NSLog(@"  ContainerView Width: %f", cell.containerView.frame.size.width);
      NSLog(@"   CardView      Width: %f", cell.cardView.frame.size.width);
  
      return cell;
  }
  </code></pre>
  
  <p>ViewController.h</p>
  
  <pre><code>@property UINib *myCardCellNib;
  </code></pre>
  
  <p>ViewController.m </p>
  
  <p>viewDidLoad:</p>
  
  <pre><code>self.myCardCellNib = [UINib nibWithNibName:@"MyCardCellTableViewCell" bundle:nil];
  [self.tableView registerNib:self.myCardCellNib forCellReuseIdentifier:@"MyCardCell"];
  [self.tableView setEstimatedRowHeight:237.0];
  [self.tableView setRowHeight:UITableViewAutomaticDimension];
  </code></pre>
  
  <p>table view cell initiatization:</p>
  
  <pre><code>#import "MyCardCellTableViewCell.h"
  
  //managers
  #import "FFFColorManager.h"
  
  @implementation MyCardCellTableViewCell
  
  - (void)awakeFromNib {
      [self initializeAppearance];
  }
  
  - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
      [super setSelected:selected animated:animated];
  }
  
  #pragma mark - Private
  
  - (void)initializeAppearance {
      [self initializeFonts];
      [self initializeColors];
  }
  
  - (void)initializeFonts {
      self.title.font = [UIFont fontWithName:@"Roboto-Regular" size:14.0];
      self.subtitle.font = [UIFont fontWithName:@"Roboto-Regular" size:12.0];
      self.username.font = [UIFont fontWithName:@"Roboto-Light" size:10.0];
  }
  
  - (void)initializeColors {
      self.respondLabel.backgroundColor = [[FFFColorManager sharedManager] colorForApplicationColorIdentifier:ApplicationColorIdentifierQuestionCardSectionRespondBackground];
      self.containerView.backgroundColor = [[FFFColorManager sharedManager] colorForApplicationColorIdentifier:ApplicationColorIdentifierTableViewBackground];
  
      UIColor *cardForegroundColor = [[FFFColorManager sharedManager] colorForApplicationColorIdentifier:ApplicationColorIdentifierQuestionCard];
      self.title.backgroundColor = cardForegroundColor;
      self.subtitle.backgroundColor = cardForegroundColor;
  }
  
  @end
  </code></pre>