title: UITableView reuse identifiers
body: <p>Till today I thought I understood UITableView properly but that perception has changed as I have been fighting scrolling and content mismatch while scrolling issues.</p>
  
  <p>I have a small table view with potentially 20-30 rows depending on user content. When I scroll (a bit faster than usual), the content gets mixed up. Some accessory views get interchanged, background colors get swapped or overwritten; sometimes even the text changes.</p>
  
  <p>I use reuse identifiers for some of cells but I am not sure its even working out properly.</p>
  
  <p>Issues:</p>
  
  <ol>
  <li><p>Clearly a single reuse identifier is not cutting it in case — as the first and the last cell swap values.</p></li>
  <li><p>With 3 reuse identifiers for first, last and remaining cells (contain settings), the accessory views get interchanged between some cells that contain settings, i.e. in some cases I use switch controls, in others I use an accessory detail button and there is blasphemy.</p></li>
  <li><p>Even with 5 reuse identifiers for different types of content, the accessory views get mismatched with background colors of other cells.</p></li>
  </ol>
  
  <p>I have been writing table views for a while and I have never encountered these issues before. So I have one simple question — When do you create reuse identifiers?</p>
  
  <ul>
  <li>only when the text/image content is different?</li>
  <li>when accessory views are same? i.e. for different accessory views create different reuse identifiers</li>
  </ul>
  
  <p>I am completely lost on this so if you can really churn out an explanation, I would be really grateful.</p>
  
  <p>EDIT: I have been working on this for the last 5 hours and have gone through a lot of literature and open/closed issues on StackOverflow. I understand what reusable cells are. The provided thread doesn't answer the very specific questions.</p>
  
  <p>Here is some code:</p>
  
  <pre><code>// previously had 3 different types of cells; currently doing with one only
  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  {
      NSString *cellIdentifier = [self cellIdentifierForIndexPath:indexPath];
  
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
      if (!cell)
      {
          cell = [[ESBasicTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
      }
  
      [self configureCell:cell atIndexPath:indexPath];
      return cell;
  }
  
  - (NSString *)cellIdentifierForIndexPath:(NSIndexPath *)indexPath
  {
      static NSString *FirstCellId = @"First";
      static NSString *SecondCellId = @"Second";
      static NSString *ThirdCellId = @"Third";
      static NSString *ForthCellId = @"Forth";
      static NSString *FifthCellId = @"Fifth";
      static NSString *SixthCellId = @"Sixth";
  
      NSString *cellIdentifier = nil;
      if (indexPath.section == kSectionFirst &amp;&amp; indexPath.row == kRowFirst)
      {
          cellIdentifier = FirstCellId;
      }
      else if (indexPath.section == kSectionFirst &amp;&amp; indexPath.row == kRowSecond)
      {
          cellIdentifier = SecondCellId;
      }
      else if (indexPath.section == kSectionSecond)
      {
          cellIdentifier = ThirdCellId;
      }
      else if (indexPath.section == kSectionThird)
      {
          cellIdentifier = ForthCellId;
      }
      else if (indexPath.section == kSectionSettings)
      {
          cellIdentifier = FifthCellId;
      }
      else if (indexPath.section == kSEctionFifth)
      {
          cellIdentifier = SixthCellId;
      }
  
      return cellIdentifier;
  }
  </code></pre>
  
  <p>The <code>configureCell:atIndexPath</code> method results in other configuration calls; one of them being configuration for settings:</p>
  
  <pre><code>- (void)configureCellForSettings:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
  {
      cell.selectionStyle = UITableViewCellSelectionStyleNone;
  
      switch (indexPath.row)
      {
          case kRowNotificationSetting:
          {
              cell.textLabel.text = @"Notifications";
              cell.accessoryType = UITableViewCellAccessoryDetailButton;
              cell.imageView.image = [[UIImage imageNamed:@"cell_notification_icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
              break;
          }
          case kRowSomeOtherSetting:
          {
              cell.textLabel.text = @"Auto";
              cell.imageView.image = [[UIImage imageNamed:@"cell_auto_icon"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
  
              UISwitch *switchView = [[UISwitch alloc] initWithFrame:CGRectZero];
              [switchView addTarget:self action:@selector(changed:) forControlEvents:UIControlEventValueChanged];
              [switchView setOn:...];
  
              cell.accessoryView = switchView;
              break;
          }
          default:
              break;
      }
  }
  </code></pre>
  
  <p>Some meaningful text has been stripped out (unfortunately). The forth section is for the settings but this is just an example.</p>
  
  <p>Edit: Here is <code>configureCell:atIndexPath:</code></p>
  
  <pre><code>- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
  {
      if (indexPath.section == kSectionFirst)
      {
          // ...
          [self configureFirstCell:cell atIndexPath:indexPath];
      }
      else if (indexPath.section == kSectionSecond)
      {
          // ...
          [self configureSecondCell:cell atIndexPath:indexPath];
      }
      else if (indexPath.section == kSectionThird)
      {
          // add ...
          [self configureThirdCell:cell atIndexPath:indexPath];
      }
      else if (indexPath.section == kSectionSettings)
      {
          // settings
          [self configureCellForSettings:cell atIndexPath:indexPath];
      }
      else if (indexPath.section == kSectionFifth)
      {
          // delete button
          [self configureFifthCell:cell atIndexPath:indexPath];
      }
  }
  </code></pre>
  
  <p>Please note — I had to rename a lot of the code to have it on StackOverflow.</p>