How to get notified when scrollToRowAtIndexPath finishes animating

前端 未结 6 1873
梦如初夏
梦如初夏 2020-11-30 09:57

This is a follow-up to How to get notified when a tableViewController finishes animating the push onto a nav stack.

In a tableView I want to deselect a

6条回答
  •  情书的邮戳
    2020-11-30 10:07

    Implementing this in a Swift extension.

    //strong ref required
    private var lastDelegate : UITableViewScrollCompletionDelegate! = nil
    
    private class UITableViewScrollCompletionDelegate : NSObject, UITableViewDelegate {
        let completion: () -> ()
        let oldDelegate : UITableViewDelegate?
        let targetOffset: CGPoint
        @objc private func scrollViewDidEndScrollingAnimation(scrollView: UIScrollView) {
            scrollView.delegate = oldDelegate
            completion()
            lastDelegate = nil
        }
    
        init(completion: () -> (), oldDelegate: UITableViewDelegate?, targetOffset: CGPoint) {
            self.completion = completion
            self.oldDelegate = oldDelegate
            self.targetOffset = targetOffset
            super.init()
            lastDelegate = self
        }
    }
    
    extension UITableView {
        func scrollToRowAtIndexPath(indexPath: NSIndexPath, atScrollPosition scrollPosition: UITableViewScrollPosition, animated: Bool, completion: () -> ()) {
            assert(lastDelegate == nil, "You're already scrolling.  Wait for the last completion before doing another one.")
            let originalOffset = self.contentOffset
            self.scrollToRowAtIndexPath(indexPath, atScrollPosition: scrollPosition, animated: false)
    
            if originalOffset.y == self.contentOffset.y { //already at the right position
                completion()
                return
            }
            else {
                let targetOffset = self.contentOffset
                self.setContentOffset(originalOffset, animated: false)
                self.delegate = UITableViewScrollCompletionDelegate(completion: completion, oldDelegate: self.delegate, targetOffset:targetOffset)
                self.scrollToRowAtIndexPath(indexPath, atScrollPosition: scrollPosition, animated: true)
            }
        }
    }
    

    This works for most cases although the TableView delegate is changed during the scroll, which may be undesired in some cases.

提交回复
热议问题