diff --git a/DGElasticPullToRefresh/DGElasticPullToRefreshConstants.swift b/DGElasticPullToRefresh/DGElasticPullToRefreshConstants.swift index af3c7ca..8202b1c 100644 --- a/DGElasticPullToRefresh/DGElasticPullToRefreshConstants.swift +++ b/DGElasticPullToRefresh/DGElasticPullToRefreshConstants.swift @@ -39,5 +39,5 @@ public struct DGElasticPullToRefreshConstants { public static var MinOffsetToPull: CGFloat = 95.0 public static var LoadingContentInset: CGFloat = 50.0 public static var LoadingViewSize: CGFloat = 30.0 - + } \ No newline at end of file diff --git a/DGElasticPullToRefresh/DGElasticPullToRefreshExtensions.swift b/DGElasticPullToRefresh/DGElasticPullToRefreshExtensions.swift index 15a9561..2674936 100644 --- a/DGElasticPullToRefresh/DGElasticPullToRefreshExtensions.swift +++ b/DGElasticPullToRefresh/DGElasticPullToRefreshExtensions.swift @@ -80,35 +80,46 @@ public extension NSObject { // MARK: (UIScrollView) Extension public extension UIScrollView { - - // MARK: - Vars + + // MARK: - + // MARK: Vars private struct dg_associatedKeys { static var pullToRefreshView = "pullToRefreshView" } - - private var pullToRefreshView: DGElasticPullToRefreshView? { + + private var _pullToRefreshView: DGElasticPullToRefreshView? { get { return objc_getAssociatedObject(self, &dg_associatedKeys.pullToRefreshView) as? DGElasticPullToRefreshView } - + set { objc_setAssociatedObject(self, &dg_associatedKeys.pullToRefreshView, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC) } } + private var pullToRefreshView: DGElasticPullToRefreshView! { + get { + if let pullToRefreshView = _pullToRefreshView { + return pullToRefreshView + } else { + let pullToRefreshView = DGElasticPullToRefreshView() + _pullToRefreshView = pullToRefreshView + return pullToRefreshView + } + } + } + // MARK: - Methods (Public) public func dg_addPullToRefreshWithActionHandler(actionHandler: () -> Void, loadingView: DGElasticPullToRefreshLoadingView?) { multipleTouchEnabled = false panGestureRecognizer.maximumNumberOfTouches = 1 - - let pullToRefreshView = DGElasticPullToRefreshView() - self.pullToRefreshView = pullToRefreshView + pullToRefreshView.actionHandler = actionHandler pullToRefreshView.loadingView = loadingView addSubview(pullToRefreshView) - + pullToRefreshView.observing = true } @@ -126,6 +137,10 @@ public extension UIScrollView { pullToRefreshView?.fillColor = color } + public func dg_startLoading() { + pullToRefreshView?.startLoading() + } + public func dg_stopLoading() { pullToRefreshView?.stopLoading() } diff --git a/DGElasticPullToRefresh/DGElasticPullToRefreshView.swift b/DGElasticPullToRefresh/DGElasticPullToRefreshView.swift index fd20c97..a06252e 100644 --- a/DGElasticPullToRefresh/DGElasticPullToRefreshView.swift +++ b/DGElasticPullToRefresh/DGElasticPullToRefreshView.swift @@ -60,6 +60,10 @@ public class DGElasticPullToRefreshView: UIView { if previousValue == .Dragging && newValue == .AnimatingBounce { loadingView?.startAnimating() animateBounce() + } else if previousValue == .Stopped && newValue == .AnimatingBounce { + loadingView?.setPullProgress(1.0) + loadingView?.startAnimating() + animateBounce() } else if newValue == .Loading && actionHandler != nil { actionHandler() } else if newValue == .AnimatingToStopped { @@ -123,7 +127,7 @@ public class DGElasticPullToRefreshView: UIView { init() { super.init(frame: CGRect.zero) - displayLink = CADisplayLink(target: self, selector: #selector(DGElasticPullToRefreshView.displayLinkTick)) + displayLink = CADisplayLink(target: self, selector: #selector(self.displayLinkTick)) displayLink.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSRunLoopCommonModes) displayLink.paused = true @@ -141,7 +145,7 @@ public class DGElasticPullToRefreshView: UIView { addSubview(r2ControlPointView) addSubview(r3ControlPointView) - NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(DGElasticPullToRefreshView.applicationWillEnterForeground), name: UIApplicationWillEnterForegroundNotification, object: nil) + NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.applicationWillEnterForeground), name: UIApplicationWillEnterForegroundNotification, object: nil) } required public init?(coder aDecoder: NSCoder) { @@ -149,14 +153,14 @@ public class DGElasticPullToRefreshView: UIView { } // MARK: - - + /** Has to be called when the receiver is no longer required. Otherwise the main loop holds a reference to the receiver which in turn will prevent the receiver from being deallocated. */ func disassociateDisplayLink() { displayLink?.invalidate() } - + deinit { observing = false NSNotificationCenter.defaultCenter().removeObserver(self) @@ -204,6 +208,14 @@ public class DGElasticPullToRefreshView: UIView { return superview as? UIScrollView } + func startLoading() { + if state != .Stopped { + return + } else { + state = .AnimatingBounce + } + } + func stopLoading() { // Prevent stop close animation if state == .AnimatingToStopped { @@ -301,12 +313,9 @@ public class DGElasticPullToRefreshView: UIView { } } - private func animateBounce() - { + private func animateBounce() { guard let scrollView = scrollView() else { return } - if (!self.observing) { return } - - + resetScrollViewContentInset(shouldAddObserverWhenFinished: false, animated: false, completion: nil) let centerY = DGElasticPullToRefreshConstants.LoadingContentInset @@ -359,7 +368,7 @@ public class DGElasticPullToRefreshView: UIView { if state == .AnimatingBounce { guard let scrollView = scrollView() else { return } - + scrollView.contentInset.top = bounceAnimationHelperView.dg_center(isAnimating()).y scrollView.contentOffset.y = -scrollView.contentInset.top @@ -369,7 +378,7 @@ public class DGElasticPullToRefreshView: UIView { } else if state == .AnimatingToStopped { height = actualContentOffsetY() } - + shapeLayer.frame = CGRect(x: 0.0, y: 0.0, width: width, height: height) shapeLayer.path = currentPath()