Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bounces property for disabling over-scroll bouncing. #20

Merged
merged 2 commits into from
Mar 13, 2017
Merged
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
25 changes: 25 additions & 0 deletions Sources/Pageboy/PageboyScrollDetection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ extension PageboyViewController: UIPageViewControllerDelegate, UIScrollViewDeleg
//

public func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard self.updateContentOffsetForBounceIfNeeded(scrollView: scrollView) == false else {
return
}

guard let currentIndex = self.currentIndex else {
return
}
Expand Down Expand Up @@ -130,6 +134,10 @@ extension PageboyViewController: UIPageViewControllerDelegate, UIScrollViewDeleg
self.scrollView(didEndScrolling: scrollView)
}

public func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
self.updateContentOffsetForBounceIfNeeded(scrollView: scrollView)
}

private func scrollView(didEndScrolling scrollView: UIScrollView) {
if self.autoScroller.restartsOnScrollEnd {
self.autoScroller.restart()
Expand Down Expand Up @@ -270,6 +278,23 @@ extension PageboyViewController: UIPageViewControllerDelegate, UIScrollViewDeleg
let pageOffset = (CGFloat(currentIndex) * pageSize) + (scrollOffset * indexDiff)
return pageOffset / pageSize
}

/// Update the scroll view contentOffset for bouncing preference if required.
///
/// - Parameter scrollView: The scroll view.
/// - Returns: Whether the contentOffset was manipulated to achieve bouncing preference.
@discardableResult private func updateContentOffsetForBounceIfNeeded(scrollView: UIScrollView) -> Bool {
guard self.bounces == false else { return false }

let previousContentOffset = scrollView.contentOffset
if self.currentIndex == 0 && scrollView.contentOffset.x < scrollView.bounds.size.width {
scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0.0)
}
if self.currentIndex == (self.viewControllers?.count ?? 1) - 1 && scrollView.contentOffset.x > scrollView.bounds.size.width {
scrollView.contentOffset = CGPoint(x: scrollView.bounds.size.width, y: 0.0)
}
return previousContentOffset != scrollView.contentOffset
}
}


Expand Down
3 changes: 3 additions & 0 deletions Sources/Pageboy/PageboyViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ open class PageboyViewController: UIViewController {
}
}

/// default YES. if YES, bounces past edge of content and back again.
public var bounces: Bool = true

/// Whether user interaction is enabled on the page view controller.
///
/// Default is TRUE
Expand Down
11 changes: 11 additions & 0 deletions Sources/PageboyTests/PageboyTransitionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,17 @@ class PageboyTransitionTests: PageboyTests {
}
}

func testBouncingDisabledTransition() {
self.dataSource.numberOfPages = 2
self.pageboyViewController.dataSource = self.dataSource
self.pageboyViewController.bounces = false

self.simulateScroll(toPosition: -0.1)

XCTAssert(self.pageboyViewController.currentPosition!.x == 0.0,
"Bounces flag is not adhered to when setting contentOffset when false.")
}

// MARK: Utils

func simulateScroll(toPosition position: CGFloat) {
Expand Down