1

In my application, i listed delivered notifications as sorted by date in tableView. If user tap to notifications from device notification screen, app highlights row. But before user presses notification on device main screen, if users scroll towards the end of the tableView, when user presses notification, app scrolls the tableView to the row with as an animated and also highlights the row.

But if users scrolled contentView to end of the tableView, highlight is not working. I think scroll to row animation function and highlight animation function working at same time.

How can i catch when tableView.scrollToRow(at: indexPath, at: .bottom, animated: true) animation finished. If i know when scrollToRow animation finish, i can run highlight row code after.

Thanks.

 DispatchQueue.main.async {
      self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
      
      if let cell = self.tableView.cellForRow(at: indexPath) as? NewsItemCell {
        
        let highlightView = UIView.init(frame: cell.contentView.frame)
        highlightView.backgroundColor = .white
        highlightView.alpha = 0.0
        cell.contentView.addSubview(highlightView)
        print(indexPath)
        
        UIView.animate(withDuration: 1.0, delay: 0, options: .curveEaseIn) {
          highlightView.alpha = 1.0
          
        } completion: { Bool in
          UIView.animate(withDuration: 1.5, delay: 0, options: .curveEaseOut) {
            highlightView.alpha = 0.0
          } completion: { Bool in
            highlightView.removeFromSuperview()
          }
        }
      }
    }
Vileriu
  • 25
  • 4
  • I would try calling `scrollToRow` with `animated` set to `false` but inside a `UIView.animate` block. Not sure if that will animate the scrolling or not. If that works for still animating the scroll, you can put your highlight code in the completion block of that `UIView.animate`. – HangarRash Nov 02 '22 at 15:20
  • 1
    Possible duplicate of: https://stackoverflow.com/questions/4356256/how-to-get-notified-when-scrolltorowatindexpath-finishes-animating – MannyCalavera27 Nov 02 '22 at 15:40
  • Does this answer your question? [How to get notified when scrollToRowAtIndexPath finishes animating](https://stackoverflow.com/questions/4356256/how-to-get-notified-when-scrolltorowatindexpath-finishes-animating) – HangarRash Nov 03 '22 at 04:19
  • Hi @HangarRash Doesn't sorry. – Vileriu Nov 04 '22 at 16:06
  • Sorry @HangarRash Duncan's wrote already. Thanks you too. – Vileriu Nov 04 '22 at 16:08
  • @Vileriu Why not? It provides the same answer as given by Duncan below. – HangarRash Nov 04 '22 at 16:08
  • @Vileriu if my answer answered your question, as suggested by your comment, then you should accept it. – Duncan C Dec 02 '22 at 13:15
  • @HangarRash I think the OP might have been saying that the linked answer didn’t provide new information (when in fact it did - the bit about wrapping a follow-on animation in a call to `Dispatch.main.async()`.) – Duncan C Dec 03 '22 at 15:27

1 Answers1

3

A UITableView is a subclass of UIScrollView.

You should be able to implement the UIScrollViewDelegate method scrollViewDidEndScrollingAnimation(_:) in your table view delegate (usually the owning view controller) and then highlight the row in your implementation of that method. (You'll probably need to add logic and state variables to track the fact that you are in this situation.)

Edit:

Note that as mentioned in the answer from @trndjc linked by HangerRash, you should your follow-on animation code from a call to Dispatch.main.async(). (That will help avoid stutters in the animations.)

From that answer:

Second, despite the fact that the method is called on the main thread, if you're running a subsequent animation here (one after the scroll has finished), it will still hitch (this may or may not be a bug in UIKit). Therefore, simply dispatch any follow-up animations back onto the main queue which just ensures that the animations will begin after the end of the current main task (which appears to include the scroll-to-row animation). Doing this will give you the appearance of a true completion.

func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
    DispatchQueue.main.async {
        // execute subsequent animation here
    }
}
Duncan C
  • 128,072
  • 22
  • 173
  • 272