title: Custom UITableview Cell Occasionally Overlapping/Reproducing On Top Of Other Cell
body: <p>Really strange problem I'm having here. </p>
  
  <p>Basically, the user comes to a View that has a TableView attached to it.  There's a call to the backend for some data, and in the completion block of that data is provided to the TableView to display. </p>
  
  <p>In cellForRow 1 of 4 reusable, custom cells is dequeued, based on some logic, and then a configure method for that cell is called.</p>
  
  <p>Here's where it gets tricky:  Some of the cells might require further asynchronous calls (to fetch more data for their custom displays), thus required a tableView.reloadRows call...What's happening, then, is best explained by these two screenshots:</p>
  
  <p><a href="https://i.stack.imgur.com/yct3v.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/yct3v.png" alt="Wrong"></a>
  <a href="https://i.stack.imgur.com/JObzd.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/JObzd.png" alt="Right"></a></p>
  
  <p>In the first one, that cell with "Ever wonder what YOU'D do for a klondike bar?" is replicated on top of the "Self-Management for Actor's" cell which, as a cell containing Twitter info DID require an additional asynch call to fetch that data.</p>
  
  <p>Any thoughts?  I'm running the tableView.reloadRows call inside of a begin/endUpdates block, but no dice.</p>
  
  <p>cellForRow:</p>
  
  <pre><code>override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
      let postAtIndexPath = posts[indexPath.row]
      let cell: PostCell!
  
      if postAtIndexPath.rawURL == "twitter.com" {
          cell = tableView.dequeueReusableCell(withIdentifier: "TwitterCell", for: indexPath) as! TwitterCell
      } else if !postAtIndexPath.rawURL.isEmpty {
          cell = tableView.dequeueReusableCell(withIdentifier: "LinkPreviewCell", for: indexPath) as! LinkPreviewCell
      } else if postAtIndexPath.quotedID &gt; -1 {
          cell = tableView.dequeueReusableCell(withIdentifier: "QuoteCell", for: indexPath) as! QuoteCell
      } else {
          cell = tableView.dequeueReusableCell(withIdentifier: "PostCell", for: indexPath) as! PostCell
      }
  
      cell.isUserInteractionEnabled = true
  
      cell.privacyDelegate = self
      cell.shareDelegate = self
      cell.likeDelegate = self
      cell.linkPreviewDelegate = self
      cell.reloadDelegate = self
      postToIndexPath[postAtIndexPath.id] = indexPath
  
      if parentView == "MyLikes" || parentView == "Trending" {
          cell.privatePostButton.isHidden = true
          cell.privatePostLabel.isHidden = true
      }
  
      cell.configureFor(post: postAtIndexPath,
                           liked: likesCache.postIsLiked(postId: postAtIndexPath.id),
                           postIdToAttributions: postIdToAttributions,
                           urlStringToOGData: urlStringToOGData,
                           imageURLStringToData: imageURLStringToData)
  
      cell.contentView.layoutIfNeeded()
  
      return cell
  }
  </code></pre>
  
  <p>asynch Twitter call:</p>
  
  <pre><code>private func processForTwitter(og: OpenGraph, urlLessString: NSMutableAttributedString, completion:(() -&gt; ())?) {
      let ogURL = og[.url]!
      let array = ogURL.components(separatedBy: "/")
      let client = TWTRAPIClient()
      let tweetID = array[array.count - 1]
      if let tweet = twitterCache.tweet(forID: Int(tweetID)!)  {
          for subView in containerView.subviews {
              subView.removeFromSuperview()
          }
  
          let tweetView = TWTRTweetView(tweet: tweet as? TWTRTweet, style: .compact)
          containerView.addSubview(tweetView)
          tweetView.translatesAutoresizingMaskIntoConstraints = false
          tweetView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor).isActive = true
          tweetView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
          containerView.leftAnchor.constraint(equalTo: tweetView.leftAnchor).isActive = true
          containerView.rightAnchor.constraint(equalTo: tweetView.rightAnchor).isActive = true
          containerView.isHidden = false
          postText.isHidden = false
  
      } else {
          client.loadTweet(withID: tweetID, completion: { [weak self] (t, error) in
              if let weakSelf = self {
                  if let tweet = t {
                      weakSelf.twitterCache.addTweetToCache(tweet: tweet, forID: Int(tweetID)!)
                  }
              }
  
              if let complete = completion {
                  complete()
              }
          })`enter code here`
      }
  
      if urlLessString.string.isEmpty {
          if let ogTitle = og[.title] {
              postText.text = String(htmlEncodedString: ogTitle)
          }
      } else {
          postText.attributedText = urlLessString
      }
  }
  </code></pre>
  
  <p>completion block in the tableviewcontroller:</p>
  
  <pre><code>func reload(postID: Int) {
  
      tableView.beginUpdates()
      self.tableView.reloadRows(at: [self.postToIndexPath[postID]!], with: .automatic)
      tableView.endUpdates()
  
  }
  </code></pre>
  
  <p>NB: this doesn't happen 100% of the time, it is, presumably, network dependent.</p>