title: swift3 uitableView reload makes screen blink
body: <p>I am using UITableview and it looks similar with the feed of Instagram. The issue I have </p>
  
  <ol>
  <li>I have a like function in each tableviewCell </li>
  <li>when tap like button, it needs to update the screen and the screen blinks </li>
  <li>In tableview cellForRowAt function, I have a network call to check the like and its number. </li>
  </ol>
  
  <p>Please let me know if there is a way to avoid this blink. Should I avoid network call in this function or is there any other way? </p>
  
  <p>U can see some part of my code below: </p>
  
  <pre><code>    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
      let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! StoryReviewTableViewCell
  
      let review = ReviewArray[indexPath.row]
  
      // 프로필 이미지랑 닉네임 설정
      if let user = review.creator {
          let nickname = user.getProperty("nickname") as! String
          cell.profileName.text = nickname
  
          if let profileURL = user.getProperty("profileURL") {
              if profileURL is NSNull {
                  cell.profileImage.image = #imageLiteral(resourceName: "user_profile")
              } else {
                  let url = URL(string: profileURL as! String)
                  DispatchQueue.main.async {
                      cell.profileImage.kf.setImage(with: url, placeholder: #imageLiteral(resourceName: "imageLoadingHolder"), options: [.transition(.fade(0.2))], progressBlock: nil, completionHandler: nil)
                  }
              }
          }
      } else {
          //  삭제된 유저의 경우
          cell.profileName.text = "탈퇴 유저"
          cell.profileImage.image = #imageLiteral(resourceName: "user_profile")
      }
  
      // 장소 이름
      if let store = ReviewArray[indexPath.row].store {
          cell.storeName.text = "장소: \(String(describing: store.name!))"
      } else {
          cell.storeName.text = "가게 이름"
      }
  
  
      // 라이크버튼 설정 - 라이크 모양은 여기서 컨트롤, delegate에서 user 라이크 컨트롤
      DispatchQueue.global(qos: .userInteractive).async {
  
          let likeStore = Backendless.sharedInstance().data.of(ReviewLikes.ofClass())
          let dataQuery = BackendlessDataQuery()
  
          let objectID = review.objectId!
          let userID = UserManager.currentUser()!.objectId!
          // print("objectID &amp; userID: \(objectID) &amp; \(userID)")
  
          // 여기서 by가 현재 유저의 objectId이어야 하고, to는 이 리뷰의 objectId이어야 한다
          dataQuery.whereClause = "by = '\(userID)' AND to = '\(objectID)'"
  
          DispatchQueue.main.async {
              likeStore?.find(dataQuery, response: { (collection) in
                  let likes = collection?.data as! [ReviewLikes]
  
                  // 하트를 안 눌렀을 때
                  if likes.count == 0 {
                      DispatchQueue.main.async {
                          cell.likeButton.setImage(#imageLiteral(resourceName: "like_bw"), for: .normal)
                      }
                  } else {
                      DispatchQueue.main.async {
                          cell.likeButton.setImage(#imageLiteral(resourceName: "like_red"), for: .normal)
                      }
                  }
  
              }, error: { (Fault) in
                  print("라이크 불러오기에서 에러: \(String(describing: Fault?.description))")
              })
  
          }
  
          // 좋아요 개수 세기
          let countQuery = BackendlessDataQuery()
          // to가 story의 objectID와 일치하면 땡
          countQuery.whereClause = "to = '\(objectID)'"
  
          let queryOptions = QueryOptions()
          queryOptions.pageSize = 1
          countQuery.queryOptions = queryOptions
  
          DispatchQueue.global(qos: .userInteractive).async {
              let matchingLikes = likeStore?.find(countQuery)
              let likeNumbers = matchingLikes?.totalObjects
  
              DispatchQueue.main.async {
                  if likeNumbers == 0 {
                      cell.likeLabel.text = "라이크 없음 ㅠ"
                  } else {
                      cell.likeLabel.text = "\(String(describing: likeNumbers!))개의 좋아요"
                  }
              }
          }
      }
  
      // 리뷰 평점 배당
      cell.ratingView.value = review.rating as! CGFloat
  
      // 리뷰 바디
      cell.reviewBody.text = review.text
  
      // 코멘트 개수 받아오기
      DispatchQueue.global(qos: .userInteractive).async {
          // 댓글수 찾기
          let tempStore = Backendless.sharedInstance().data.of(ReviewComment.ofClass())
  
          let reviewId = review.objectId!
          let dataQuery = BackendlessDataQuery()
          // 이 리뷰에 달린 댓글 모두 몇 개인지 찾기
          dataQuery.whereClause = "to = '\(reviewId)'"
  
          DispatchQueue.main.async {
              tempStore?.find(dataQuery, response: { (collection) in
                  let comments = collection?.data as! [ReviewComment]
  
                  cell.replyLabel.text = "댓글 \(comments.count)개"
  
              }, error: { (Fault) in
                  print("서버에서 댓글 얻어오기 실패: \(String(describing: Fault?.description))")
              })
          }
      }
  
      cell.timeLabel.text = dateFormatter.string(from: review.created! as Date)
  
      return cell
  }
  </code></pre>
  
  <p>U can see the button action here </p>
  
  <pre><code>    @IBAction func likeButtonClicked(_ sender: UIButton) {
  
      likeButton.isUserInteractionEnabled = false
  
      // delegate action
      delegate?.actionTapped(tag: likeButton.tag)
  
      // image change
      if sender.image(for: .normal) == #imageLiteral(resourceName: "like_bw") {
          UIView.transition(with: sender, duration: 0.2, options: .transitionCrossDissolve, animations: {
              sender.setImage(#imageLiteral(resourceName: "like_red"), for: .normal)
          }, completion: nil)
          self.likeButton.isUserInteractionEnabled = true
      } else {
          UIView.transition(with: sender, duration: 0.2, options: .transitionCrossDissolve, animations: {
              sender.setImage(#imageLiteral(resourceName: "like_bw"), for: .normal)
          }, completion: nil)
          self.likeButton.isUserInteractionEnabled = true
      }
  }
  </code></pre>
  
  <p>This is part of my delegate function which reload only for the row </p>
  
  <pre><code>    func changeLike(_ row: Int, _ alreadyLike: Bool, completionHandler: @escaping (_ success:Bool) -&gt; Void) {
  
      let selectedReview = ReviewArray[row]
      let reviewId = selectedReview.objectId
  
      // 그냥 유저 객체로 비교는 안되고 objectId로 체크를 해야 함
      let objectID = Backendless.sharedInstance().userService.currentUser.objectId
  
      let dataStore = Backendless.sharedInstance().data.of(ReviewLikes.ofClass())
  
      // 좋아요 - alreadyLike가 true이면
      if !alreadyLike {
          // 객체 생성
  
          let like = ReviewLikes()
          like.by = objectID! as String
          like.to = reviewId
  
          dataStore?.save(like, response: { (response) in
  
              DispatchQueue.main.async {
  
                  let indexPath = IndexPath(row: row, section: 0)
                  self.tableView.reloadRows(at: [indexPath], with: .none)
  
              }
      }
  </code></pre>