title: Need help to line progress with animation in UITableViewCell
body: <p>I have couple of row and each row have a state and states are (Waiting, in-progress, done). Also each row have a title, imageView, topLine and a bottomLine.</p>
  
  <p>Depending on state of the row, I need to animate the line progress and change the image in imageView with animation. </p>
  
  <p>Till now I have done the image change in imageView with animation but it's not perfect. It's showing animation while scrolling. Also, I tried line progress animation with UIBezierPath, but not succeed. It's fluctuate while scrolling. <a href="https://i.stack.imgur.com/HIvos.png" rel="nofollow noreferrer">Sample Image</a></p>
  
  <p>I want to achieve, line will draw with a animation and image will change on that time only while line are animating on the cell. It should not fluctuate while we scroll the tableView.</p>
  
  <p>Some code reference </p>
  
  <p>In cellForRowAtindexPath</p>
  
  <pre><code> let cell = tableview.dequeueReusableCell(withIdentifier: "AnimationTableViewCell") as? AnimationTableViewCell
  
          // code block without animation. Only image animation done but its not perfect
          /*switch indexPath.row {
          case 0:
              let firstIndex = 0
              let nextIndex = 1
              cell?.animateFrom(first: arrItem[firstIndex], to: arrItem[nextIndex])
          case arrItem.count - 1:
              let currentIndex = indexPath.row
              let prevIndex = currentIndex - 1
              cell?.animateFrom(previous: arrItem[prevIndex], to: arrItem[currentIndex])
          default:
              let currentIndex = indexPath.row
              let prevIndex = currentIndex - 1
              let nextIndex = currentIndex + 1
              cell?.animate(previous: arrItem[prevIndex], current: arrItem[currentIndex], next: arrItem[nextIndex])
          }
          cell?.changeImageWithAnimation(arrItem[indexPath.row].state, row: indexPath.row)*/
  
          // code block with improper animation
          if (cell?.shapeLayer == nil) {
              cell?.doAnimation(state: arrItem[indexPath.row].state, row: indexPath.row, isFirstTime: firstTime)
          }
          cell?.lblTitle.text = arrItem[indexPath.row].title
          cell?.clipsToBounds = true
          cell?.selectionStyle = .none
  
          return cell!
  </code></pre>
  
  <p>in AnimationTableViewCell</p>
  
  <pre><code>func doAnimation(state: ProgressType, row: Int = 0, isFirstTime: Bool) {
  
          NSLog("\(row)")
  
          guard isFirstTime else {
              return
          }
  //        DispatchQueue.main.asyncAfter(deadline: &lt;#T##DispatchTime#&gt;, execute: &lt;#T##() -&gt; Void#&gt;)
          DispatchQueue.main.asyncAfter(deadline: (DispatchTime.now() + .seconds(row))) {
  
              self.shapeLayer?.removeFromSuperlayer()
  
              // create whatever path you want
  
              let path = UIBezierPath()
              path.move(to: CGPoint(x: self.lblTopLine.frame.origin.x, y: 0))
              path.addLine(to: CGPoint(x: self.lblTopLine.frame.origin.x, y: 74))
              path.addLine(to: CGPoint(x: self.lblTopLine.frame.origin.x, y: 148))
  
              // create shape layer for that path
  
              let shapeLayer = CAShapeLayer()
              shapeLayer.fillColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0).cgColor
              shapeLayer.strokeColor = state.color().cgColor
              //        shapeLayer.strokeColor = #colorLiteral(red: 1, green: 0, blue: 0, alpha: 1).cgColor
              shapeLayer.lineWidth = 4
              shapeLayer.path = path.cgPath
  
              // animate it
  
              self.layer.addSublayer(shapeLayer)
              let animation = CABasicAnimation(keyPath: "strokeEnd")
              animation.fromValue = 0
              animation.duration = 1
              shapeLayer.add(animation, forKey: "MyAnimation")
  
  //             save shape layer
  
              self.shapeLayer = shapeLayer
  
              DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
  //                self.lblTopLine.backgroundColor = state.color()
  //                self.lblBottomLine.backgroundColor = state.color()
  //                self.shapeLayer?.removeFromSuperlayer()
              })
  
              self.imgView.image = UIImage(named: "initial")
              self.imgView.backgroundColor = UIColor.clear
              DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(250), execute: {
                  UIView.animate(withDuration: 0.5, animations: {
                      self.imgView.backgroundColor = UIColor.red
                  })
  
                  UIView.transition(with: self.imgView, duration: 0.5, options: UIView.AnimationOptions.transitionCrossDissolve, animations: {
                      self.imgView.image = UIImage(named: "tick")
                  }, completion: nil)
              })
          }
      }
  </code></pre>
  
  <p>You can download sample project from <a href="https://www.dropbox.com/s/tftirbxtrw8v1bh/ProgressAnimation.zip?dl=0" rel="nofollow noreferrer">here</a>. </p>