From 788a5ae73c46d38b7d333d0955ef0fa4c96bb3fe Mon Sep 17 00:00:00 2001 From: Mikhail Konovalov Date: Thu, 11 Jan 2018 12:03:56 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=83=20=D1=81=20KVO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Classes/RMRPullToRefreshConstants.swift | 8 --- Classes/RMRPullToRefreshController.swift | 84 ++++++++---------------- 2 files changed, 29 insertions(+), 63 deletions(-) diff --git a/Classes/RMRPullToRefreshConstants.swift b/Classes/RMRPullToRefreshConstants.swift index 699c372..341a41c 100755 --- a/Classes/RMRPullToRefreshConstants.swift +++ b/Classes/RMRPullToRefreshConstants.swift @@ -27,14 +27,6 @@ public enum RMRPullToRefreshResultType: Int { public struct RMRPullToRefreshConstants { - struct KeyPaths { - static let ContentOffset = "contentOffset" - static let ContentSize = "contentSize" - static let ContentInset = "contentInset" - static let PanState = "pan.state" - static let Frame = "frame" - } - static let DefaultHeight = CGFloat(90.0) static let DefaultBackgroundColor = UIColor.white } diff --git a/Classes/RMRPullToRefreshController.swift b/Classes/RMRPullToRefreshController.swift index f9482fb..952bfde 100755 --- a/Classes/RMRPullToRefreshController.swift +++ b/Classes/RMRPullToRefreshController.swift @@ -7,26 +7,6 @@ // import UIKit -fileprivate func < (lhs: T?, rhs: T?) -> Bool { - switch (lhs, rhs) { - case let (l?, r?): - return l < r - case (nil, _?): - return true - default: - return false - } -} - -fileprivate func > (lhs: T?, rhs: T?) -> Bool { - switch (lhs, rhs) { - case let (l?, r?): - return l > r - default: - return rhs < lhs - } -} - open class RMRPullToRefreshController: NSObject { @@ -41,7 +21,6 @@ open class RMRPullToRefreshController: NSObject { var backgroundViewTopConstraint: NSLayoutConstraint? var stopped = true - var subscribing = false var actionHandler: (() -> Void)! @@ -60,6 +39,12 @@ open class RMRPullToRefreshController: NSObject { open var hideWhenError: Bool = true + // MARK: - Observation + + private var contentOffsetObservation: NSKeyValueObservation? + private var contentSizeObservation: NSKeyValueObservation? + private var panStateObservation: NSKeyValueObservation? + // MARK: - Init init(scrollView: UIScrollView, position:RMRPullToRefreshPosition, actionHandler: @escaping () -> Void) { @@ -319,8 +304,10 @@ open class RMRPullToRefreshController: NSObject { } else { constant = contentOffsetY + contentInset.bottom } - if constant > 0 && constant > backgroundViewHeightConstraint?.constant { - backgroundViewHeightConstraint?.constant = constant + if let backgroundViewHeightConstraint = backgroundViewHeightConstraint, + constant > 0, + constant > backgroundViewHeightConstraint.constant { + backgroundViewHeightConstraint.constant = constant } } @@ -391,41 +378,28 @@ open class RMRPullToRefreshController: NSObject { // MARK: - KVO open func subscribeOnScrollViewEvents() { - if !subscribing, let scrollView = self.scrollView { - scrollView.addObserver(self, forKeyPath: RMRPullToRefreshConstants.KeyPaths.ContentOffset, options: .new, context: nil) - scrollView.addObserver(self, forKeyPath: RMRPullToRefreshConstants.KeyPaths.ContentSize, options: .new, context: nil) - scrollView.addObserver(self, forKeyPath: RMRPullToRefreshConstants.KeyPaths.PanState, options: .new, context: nil) - subscribing = true + guard let scrollView = scrollView else { + return + } + + self.contentOffsetObservation = scrollView.observe(\.contentOffset, options: [.new]) { scrollView, change in + guard let newContentOffset = change.newValue else { return } + self.scrollViewDidScroll(scrollView, contentOffset: newContentOffset) + } + + self.contentSizeObservation = scrollView.observe(\.contentSize, options: [.new]) { scrollView, change in + guard let newContentSize = change.newValue else { return } + self.scrollViewDidChangeContentSize(scrollView, contentSize: newContentSize) + } + + self.panStateObservation = scrollView.panGestureRecognizer.observe(\.state, options: [.new]) { panGestureRecognizer, _ in + self.scrollViewDidChangePanState(scrollView, panState: panGestureRecognizer.state) } } open func unsubscribeFromScrollViewEvents() { - if subscribing, let scrollView = self.containerView.superview { - scrollView.removeObserver(self, forKeyPath: RMRPullToRefreshConstants.KeyPaths.ContentOffset) - scrollView.removeObserver(self, forKeyPath: RMRPullToRefreshConstants.KeyPaths.ContentSize) - scrollView.removeObserver(self, forKeyPath: RMRPullToRefreshConstants.KeyPaths.PanState) - subscribing = false - } + contentOffsetObservation?.invalidate() + contentSizeObservation?.invalidate() + panStateObservation?.invalidate() } - - override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { - if keyPath == RMRPullToRefreshConstants.KeyPaths.ContentOffset { - if let newContentOffset = (change?[NSKeyValueChangeKey.newKey] as? NSValue)?.cgPointValue, let scrollView = self.scrollView { - scrollViewDidScroll(scrollView, contentOffset:newContentOffset) - } - } else if keyPath == RMRPullToRefreshConstants.KeyPaths.ContentSize { - if let newContentSize = (change?[NSKeyValueChangeKey.newKey] as? NSValue)?.cgSizeValue, let scrollView = self.scrollView { - if checkContentSize(scrollView) { - scrollViewDidChangeContentSize(scrollView, contentSize: newContentSize) - } - } - } else if keyPath == RMRPullToRefreshConstants.KeyPaths.PanState { - if let rawValue = change?[NSKeyValueChangeKey.newKey] as? Int { - if let state = UIGestureRecognizerState(rawValue: rawValue), let scrollView = self.scrollView { - scrollViewDidChangePanState(scrollView, panState: state) - } - } - } - } - }