Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions DGElasticPullToRefresh/DGElasticPullToRefreshConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ public struct DGElasticPullToRefreshConstants {
static let PanGestureRecognizerState = "panGestureRecognizer.state"
}

static let WaveMaxHeight: CGFloat = 70.0
static let MinOffsetToPull: CGFloat = 95.0
static let LoadingContentInset: CGFloat = 50.0
static let LoadingViewSize: CGFloat = 30.0
public static var WaveMaxHeight: CGFloat = 70.0
public static var MinOffsetToPull: CGFloat = 95.0
public static var LoadingContentInset: CGFloat = 50.0
public static var LoadingViewSize: CGFloat = 30.0
}
60 changes: 17 additions & 43 deletions DGElasticPullToRefresh/DGElasticPullToRefreshExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -81,80 +81,54 @@ public extension NSObject {

public extension UIScrollView {

// MARK: -
// MARK: Vars

// MARK: - Vars

private struct dg_associatedKeys {
static var pullToRefreshView = "pullToRefreshView"
}
private var _pullToRefreshView: DGElasticPullToRefreshView? {

private var pullToRefreshView: DGElasticPullToRefreshView? {
get {
if let pullToRefreshView = objc_getAssociatedObject(self, &dg_associatedKeys.pullToRefreshView) as? DGElasticPullToRefreshView {
return pullToRefreshView
}

return nil
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: -
// MARK: Methods (Public)

public func dg_addPullToRefreshWithActionHandler(actionHandler: () -> Void) {
dg_addPullToRefreshWithActionHandler(actionHandler, loadingView: nil)
}
// 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
}

public func dg_removePullToRefresh() {
pullToRefreshView.observing = false
pullToRefreshView.removeFromSuperview()
pullToRefreshView?.disassociateDisplayLink()
pullToRefreshView?.observing = false
pullToRefreshView?.removeFromSuperview()
}

public func dg_setPullToRefreshBackgroundColor(color: UIColor) {
pullToRefreshView.backgroundColor = color
pullToRefreshView?.backgroundColor = color
}

public func dg_setPullToRefreshFillColor(color: UIColor) {
pullToRefreshView.fillColor = color
pullToRefreshView?.fillColor = color
}

public func dg_stopLoading() {
pullToRefreshView.stopLoading()
}

func dg_stopScrollingAnimation() {
if let superview = self.superview, let index = superview.subviews.indexOf({ $0 == self }) as Int! {
removeFromSuperview()
superview.insertSubview(self, atIndex: index)
}
pullToRefreshView?.stopLoading()
}

}

// MARK: -
Expand Down
51 changes: 30 additions & 21 deletions DGElasticPullToRefresh/DGElasticPullToRefreshView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,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)
Expand All @@ -162,7 +169,6 @@ public class DGElasticPullToRefreshView: UIView {
if keyPath == DGElasticPullToRefreshConstants.KeyPaths.ContentOffset {
if let newContentOffsetY = change?[NSKeyValueChangeNewKey]?.CGPointValue.y, let scrollView = scrollView() {
if state.isAnyOf([.Loading, .AnimatingToStopped]) && newContentOffsetY < -scrollView.contentInset.top {
scrollView.dg_stopScrollingAnimation()
scrollView.contentOffset.y = -scrollView.contentInset.top
} else {
scrollViewDidChangeContentOffset(dragging: scrollView.dragging)
Expand Down Expand Up @@ -252,7 +258,6 @@ public class DGElasticPullToRefreshView: UIView {
} else if state == .Dragging && dragging == false {
if offsetY >= DGElasticPullToRefreshConstants.MinOffsetToPull {
state = .AnimatingBounce
scrollView()?.dg_stopScrollingAnimation()
} else {
state = .Stopped
}
Expand All @@ -278,7 +283,7 @@ public class DGElasticPullToRefreshView: UIView {

let animationBlock = { scrollView.contentInset = contentInset }
let completionBlock = { () -> Void in
if shouldAddObserverWhenFinished {
if shouldAddObserverWhenFinished && self.observing {
scrollView.dg_addObserver(self, forKeyPath: DGElasticPullToRefreshConstants.KeyPaths.ContentInset)
}
completion?()
Expand Down Expand Up @@ -308,25 +313,29 @@ public class DGElasticPullToRefreshView: UIView {
startDisplayLink()
scrollView.dg_removeObserver(self, forKeyPath: DGElasticPullToRefreshConstants.KeyPaths.ContentOffset)
scrollView.dg_removeObserver(self, forKeyPath: DGElasticPullToRefreshConstants.KeyPaths.ContentInset)
UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.43, initialSpringVelocity: 0.0, options: [], animations: { () -> Void in
self.cControlPointView.center.y = centerY
self.l1ControlPointView.center.y = centerY
self.l2ControlPointView.center.y = centerY
self.l3ControlPointView.center.y = centerY
self.r1ControlPointView.center.y = centerY
self.r2ControlPointView.center.y = centerY
self.r3ControlPointView.center.y = centerY
}, completion: { _ in
self.stopDisplayLink()
self.resetScrollViewContentInset(shouldAddObserverWhenFinished: true, animated: false, completion: nil)
scrollView.dg_addObserver(self, forKeyPath: DGElasticPullToRefreshConstants.KeyPaths.ContentOffset)
scrollView.scrollEnabled = true
self.state = .Loading
})
UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.43, initialSpringVelocity: 0.0, options: [], animations: { [weak self] in
self?.cControlPointView.center.y = centerY
self?.l1ControlPointView.center.y = centerY
self?.l2ControlPointView.center.y = centerY
self?.l3ControlPointView.center.y = centerY
self?.r1ControlPointView.center.y = centerY
self?.r2ControlPointView.center.y = centerY
self?.r3ControlPointView.center.y = centerY
}, completion: { [weak self] _ in
self?.stopDisplayLink()
self?.resetScrollViewContentInset(shouldAddObserverWhenFinished: true, animated: false, completion: nil)
if let strongSelf = self, scrollView = strongSelf.scrollView() {
scrollView.dg_addObserver(strongSelf, forKeyPath: DGElasticPullToRefreshConstants.KeyPaths.ContentOffset)
scrollView.scrollEnabled = true
}
self?.state = .Loading
})

bounceAnimationHelperView.center = CGPoint(x: 0.0, y: originalContentInsetTop + currentHeight())
UIView.animateWithDuration(duration * 0.4, animations: { () -> Void in
self.bounceAnimationHelperView.center = CGPoint(x: 0.0, y: self.originalContentInsetTop + DGElasticPullToRefreshConstants.LoadingContentInset)
UIView.animateWithDuration(duration * 0.4, animations: { [weak self] in
if let contentInsetTop = self?.originalContentInsetTop {
self?.bounceAnimationHelperView.center = CGPoint(x: 0.0, y: contentInsetTop + DGElasticPullToRefreshConstants.LoadingContentInset)
}
}, completion: nil)
}

Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Open and run the DGElasticPullToRefreshExample project in Xcode to see DGElastic

## Installation

### Cocoapods
### CocoaPods

``` ruby
pod "DGElasticPullToRefresh"
Expand Down Expand Up @@ -81,6 +81,12 @@ Remove pull to refresh:
func dg_removePullToRefresh()
```

Set auto start loading:

``` swift
func dg_startLoading()
```

Change pull to refresh background color:

``` swift
Expand Down