Skip to content

Commit

Permalink
Merge pull request #139 from fermoya/develop
Browse files Browse the repository at this point in the history
1.12.0 #minor
  • Loading branch information
fermoya authored Oct 25, 2020
2 parents 6ccc32c + 957c5c4 commit 0883ceb
Show file tree
Hide file tree
Showing 15 changed files with 181 additions and 21 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/create-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ jobs:
steps:
- uses: actions/checkout@v2

- name: Select Xcode 12
run: sudo xcode-select -s /Applications/Xcode_12.app/Contents/Developer

- name: Create XCFramework
uses: unsignedapps/swift-create-xcframework@v1

Expand Down
4 changes: 4 additions & 0 deletions Example/SwiftUIPagerExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
17D9E0FD23D4CF6900C5AE93 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 17D9E0FC23D4CF6900C5AE93 /* Assets.xcassets */; };
17D9E10023D4CF6900C5AE93 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17D9E0FE23D4CF6900C5AE93 /* LaunchScreen.storyboard */; };
6B22DC81247E5C9A00EF95C5 /* NestedExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B22DC80247E5C9A00EF95C5 /* NestedExampleView.swift */; };
6B35B6C125346610000D618F /* PaginationSensitivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B35B6C025346610000D618F /* PaginationSensitivity.swift */; };
6B4EC8A2240D072B001E7490 /* ColorsExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B4EC8A1240D072B001E7490 /* ColorsExampleView.swift */; };
6B4EC8A4240D07D5001E7490 /* InfiniteExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B4EC8A3240D07D5001E7490 /* InfiniteExampleView.swift */; };
6B4EC8A6240D0918001E7490 /* EmbeddedExampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B4EC8A5240D0918001E7490 /* EmbeddedExampleView.swift */; };
Expand Down Expand Up @@ -59,6 +60,7 @@
17D9E0FF23D4CF6900C5AE93 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
17D9E10123D4CF6900C5AE93 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
6B22DC80247E5C9A00EF95C5 /* NestedExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NestedExampleView.swift; sourceTree = "<group>"; };
6B35B6C025346610000D618F /* PaginationSensitivity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PaginationSensitivity.swift; path = ../../Sources/SwiftUIPager/PageConfiguration/PaginationSensitivity.swift; sourceTree = "<group>"; };
6B4EC8A1240D072B001E7490 /* ColorsExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorsExampleView.swift; sourceTree = "<group>"; };
6B4EC8A3240D07D5001E7490 /* InfiniteExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfiniteExampleView.swift; sourceTree = "<group>"; };
6B4EC8A5240D0918001E7490 /* EmbeddedExampleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmbeddedExampleView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -187,6 +189,7 @@
children = (
6BCF139124B2677B00AADE74 /* ContentLoadingPolicy.swift */,
6BEA731224ACF8D7007EA8DC /* GesturePriority.swift */,
6B35B6C025346610000D618F /* PaginationSensitivity.swift */,
6B6FAA3C24D553C8000D1539 /* PagingAnimation.swift */,
6BEA730F24ACF8D7007EA8DC /* PositionAlignment.swift */,
6BEA731024ACF8D7007EA8DC /* SwipeDirection.swift */,
Expand Down Expand Up @@ -283,6 +286,7 @@
6BC5EDFF24866D9500E1E78C /* Buildable.swift in Sources */,
6B9C4A8A24B45F66004C06C5 /* OnDeactivateModifier.swift in Sources */,
6BEA731624ACF8D7007EA8DC /* GesturePriority.swift in Sources */,
6B35B6C125346610000D618F /* PaginationSensitivity.swift in Sources */,
6BEA731324ACF8D7007EA8DC /* PositionAlignment.swift in Sources */,
6BEA731424ACF8D7007EA8DC /* SwipeDirection.swift in Sources */,
6BC5EE0224866D9500E1E78C /* PagerContent+Helper.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct InfiniteExampleView: View {
}
.pagingPriority(.simultaneous)
.loopPages()
.sensitivity(.high)
.itemSpacing(10)
.itemAspectRatio(1.3, alignment: .start)
.padding(20)
Expand Down
43 changes: 43 additions & 0 deletions Sources/SwiftUIPager/PageConfiguration/PaginationSensitivity.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// PaginationSensitivity.swift
// SwiftUIPagerExample
//
// Created by Fernando Moya de Rivas on 12/10/2020.
// Copyright © 2020 Fernando Moya de Rivas. All rights reserved.
//

import CoreGraphics

/// Defines how sensitive the pagination is to determine whether or not to move to the next the page.
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
public enum PaginationSensitivity: Equatable {

/// The shift relative to container size needs to be greater than or equal to 75%
case low

/// The shift relative to container size needs to be greater than or equal to 50%
case medium

/// The shift relative to container size needs to be greater than or equal to 25%
case high

/// The shift relative to container size needs to be greater than or equal to the specified value
case custom(CGFloat)

/// The shift relative to container size needs to be greater than or equal to 50%
public static var `default`: Self = .medium

var value: CGFloat {
switch self {
case .low:
return 0.75
case .high:
return 0.25
case .medium:
return 0.5
case .custom(let value):
return value
}
}

}
12 changes: 9 additions & 3 deletions Sources/SwiftUIPager/Pager+Buildable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ import SwiftUI
@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
extension Pager: Buildable, PagerProxy {

public typealias DraggingResult = (page: Int, newPage: Int, translation: CGFloat, velocity: Double)
/// Result of paginating
public typealias DragResult = (page: Int, newPage: Int, translation: CGFloat, velocity: Double)

/// Sets the animation to be applied when the user stops dragging
///
/// - Parameter value: callback to get an animation based on the result of dragging
public func pagingAnimation(_ value: ((DraggingResult) -> PagingAnimation)?) -> Self {
public func pagingAnimation(_ value: ((DragResult) -> PagingAnimation)?) -> Self {
mutating(keyPath: \.pagingAnimation, value: value)
}

Expand Down Expand Up @@ -51,16 +52,21 @@ extension Pager: Buildable, PagerProxy {
.mutating(keyPath: \.loopingCount, value: count)
}

/// Disables dragging on `Pager`
#if !os(tvOS)

/// Sensitivity used to determine whether or not to swipe the page
public func sensitivity(_ value: PaginationSensitivity) -> Self {
mutating(keyPath: \.sensitivity, value: value)
}

/// Makes `Pager` not delay gesture recognition
///
/// - Parameter value: whether or not touches should be delayed
public func delaysTouches(_ value: Bool) -> Self {
mutating(keyPath: \.delaysTouches, value: value)
}

/// Disables dragging on `Pager`
public func disableDragging() -> Self {
mutating(keyPath: \.allowsDragging, value: false)
}
Expand Down
6 changes: 5 additions & 1 deletion Sources/SwiftUIPager/Pager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ public struct Pager<Element, ID, PageView>: View where PageView: View, Element:
/*** ViewModified properties ***/

/// Animation to be applied when the user stops dragging
var pagingAnimation: ((DraggingResult) -> PagingAnimation)?
var pagingAnimation: ((DragResult) -> PagingAnimation)?

/// Sensitivity used to determine whether or not to swipe the page
var sensitivity: PaginationSensitivity = .default

/// Policy to be applied when loading content
var contentLoadingPolicy: ContentLoadingPolicy = .default
Expand Down Expand Up @@ -204,6 +207,7 @@ public struct Pager<Element, ID, PageView>: View where PageView: View, Element:
.allowsDragging(allowsDragging)
.pagingPriority(gesturePriority)
.delaysTouches(delaysTouches)
.sensitivity(sensitivity)
#endif

pagerContent = allowsMultiplePagination ? pagerContent.multiplePagination() : pagerContent
Expand Down
7 changes: 6 additions & 1 deletion Sources/SwiftUIPager/PagerContent+Buildable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extension Pager.PagerContent: Buildable, PagerProxy {
/// Sets the animation to be applied when the user stops dragging
///
/// - Parameter value: callback to get an animation based on the result of dragging
func pagingAnimation(_ value: ((Pager.DraggingResult) -> PagingAnimation)?) -> Self {
func pagingAnimation(_ value: ((Pager.DragResult) -> PagingAnimation)?) -> Self {
mutating(keyPath: \.pagingAnimation, value: value)
}

Expand Down Expand Up @@ -58,6 +58,11 @@ extension Pager.PagerContent: Buildable, PagerProxy {

#if !os(tvOS)

/// Sensitivity used to determine whether or not to swipe the page
func sensitivity(_ value: PaginationSensitivity) -> Self {
mutating(keyPath: \.sensitivity, value: value)
}

/// Makes `Pager` not delay gesture recognition
///
/// - Parameter value: whether or not touches should be delayed
Expand Down
12 changes: 10 additions & 2 deletions Sources/SwiftUIPager/PagerContent+Helper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,18 @@ extension Pager.PagerContent {
return totalOffset < 0 ? .forward : .backward
}

/// The current page index. Will equal `page` if not dragging
/// Current page index, sensitivity 50%. Will equal `page` if not dragging
var currentPage: Int {
currentPage(sensitivity: 0.5)
}

/// Current page index, based on sensitivity. Will equal `page` if not dragging
func currentPage(sensitivity: CGFloat) -> Int {
guard isDragging else { return page }
let newPage = -Int((totalOffset / pageDistance).rounded()) + page
let dOffset = totalOffset / pageDistance
let remaining = dOffset - dOffset.rounded(.towardZero)
let dPage = Int(dOffset.rounded(.towardZero)) + (abs(remaining) < sensitivity ? 0 : Int(remaining.rounded(.awayFromZero)))
let newPage = page - dPage

guard isInifinitePager else { return max(min(newPage, numberOfPages - 1), 0) }
guard numberOfPages > 0 else { return 0 }
Expand Down
17 changes: 9 additions & 8 deletions Sources/SwiftUIPager/PagerContent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ extension Pager {
/*** ViewModified properties ***/

/// Animation to be applied when the user stops dragging
var pagingAnimation: ((DraggingResult) -> PagingAnimation)?
var pagingAnimation: ((DragResult) -> PagingAnimation)?

/// Sensitivity used to determine whether or not to swipe the page
var sensitivity: PaginationSensitivity = .default

/// Policy to be applied when loading content
var contentLoadingPolicy: ContentLoadingPolicy = .default
Expand Down Expand Up @@ -156,10 +159,8 @@ extension Pager {
let stack = HStack(spacing: interactiveItemSpacing) {
ForEach(dataDisplayed, id: id) { item in
Group {
if self.isInifinitePager {
self.content(item.element)
.opacity(self.isInifinitePager && self.isEdgePage(item) ? 0 : 1)
.animation(nil) // disable animation for opacity
if self.isInifinitePager && self.isEdgePage(item) {
EmptyView()
} else {
self.content(item.element)
}
Expand Down Expand Up @@ -251,7 +252,7 @@ extension Pager.PagerContent {
}

func onDragGestureEnded() {
let draggingResult = self.draggingResult
let draggingResult = self.dragResult
let newPage = draggingResult.page
let pageIncrement = draggingResult.increment

Expand All @@ -274,8 +275,8 @@ extension Pager.PagerContent {
}
}

private var draggingResult: (page: Int, increment: Int) {
let currentPage = self.currentPage
private var dragResult: (page: Int, increment: Int) {
let currentPage = self.currentPage(sensitivity: sensitivity.value)
let velocity = -self.draggingVelocity

guard allowsMultiplePagination else {
Expand Down
12 changes: 12 additions & 0 deletions SwiftUIPager.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
6B2C305F248D740800E528F9 /* PagerContent+Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BDE442823DE12480022A2F7 /* PagerContent+Helper.swift */; };
6B2C3061248D740800E528F9 /* libswiftCore.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B2C2FFC248D58F300E528F9 /* libswiftCore.tbd */; settings = {ATTRIBUTES = (Weak, ); }; };
6B2C3062248D740800E528F9 /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B2C2FDE248D379D00E528F9 /* SwiftUI.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
6B362CBD2534940B008DB2DF /* PaginationSensitivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B362CBC2534940B008DB2DF /* PaginationSensitivity.swift */; };
6B362CBE2534940B008DB2DF /* PaginationSensitivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B362CBC2534940B008DB2DF /* PaginationSensitivity.swift */; };
6B362CBF2534940B008DB2DF /* PaginationSensitivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B362CBC2534940B008DB2DF /* PaginationSensitivity.swift */; };
6B362CC02534940B008DB2DF /* PaginationSensitivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B362CBC2534940B008DB2DF /* PaginationSensitivity.swift */; };
6B362CC12534940B008DB2DF /* PaginationSensitivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B362CBC2534940B008DB2DF /* PaginationSensitivity.swift */; };
6B6FAA3F24D56BAC000D1539 /* PagingAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B6FAA3E24D56BAC000D1539 /* PagingAnimation.swift */; };
6B6FAA4024D56BAC000D1539 /* PagingAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B6FAA3E24D56BAC000D1539 /* PagingAnimation.swift */; };
6B6FAA4124D56BAC000D1539 /* PagingAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B6FAA3E24D56BAC000D1539 /* PagingAnimation.swift */; };
Expand Down Expand Up @@ -135,6 +140,7 @@
6B2C3001248D592100E528F9 /* libswiftCore.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libswiftCore.tbd; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS13.4.sdk/usr/lib/swift/libswiftCore.tbd; sourceTree = DEVELOPER_DIR; };
6B2C3067248D740800E528F9 /* SwiftUIPager.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftUIPager.framework; sourceTree = BUILT_PRODUCTS_DIR; };
6B2C3069248D747700E528F9 /* Info-Catalyst.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-Catalyst.plist"; sourceTree = "<group>"; };
6B362CBC2534940B008DB2DF /* PaginationSensitivity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PaginationSensitivity.swift; path = Sources/SwiftUIPager/PageConfiguration/PaginationSensitivity.swift; sourceTree = SOURCE_ROOT; };
6B3F9C052488E6FE00AF5E74 /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = "<group>"; };
6B6FAA3E24D56BAC000D1539 /* PagingAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = PagingAnimation.swift; path = Sources/SwiftUIPager/PageConfiguration/PagingAnimation.swift; sourceTree = SOURCE_ROOT; };
6BBC3D6B2488DBE8004194BD /* SwiftUIPager.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftUIPager.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -275,6 +281,7 @@
children = (
6BCF138B24B2674800AADE74 /* ContentLoadingPolicy.swift */,
6BEA731A24ACF9B0007EA8DC /* GesturePriority.swift */,
6B362CBC2534940B008DB2DF /* PaginationSensitivity.swift */,
6B6FAA3E24D56BAC000D1539 /* PagingAnimation.swift */,
6BEA731924ACF9B0007EA8DC /* PositionAlignment.swift */,
6BEA731724ACF9AF007EA8DC /* SwipeDirection.swift */,
Expand Down Expand Up @@ -561,6 +568,7 @@
6BEF51A624C9ED34000DF66B /* PagerProxy.swift in Sources */,
6BCF138E24B2674F00AADE74 /* ContentLoadingPolicy.swift in Sources */,
172F4D5823DF830600FD2F15 /* Buildable.swift in Sources */,
6B362CBF2534940B008DB2DF /* PaginationSensitivity.swift in Sources */,
172F4D5923DF830600FD2F15 /* Pager.swift in Sources */,
6BEA732724ACFA03007EA8DC /* SwipeDirection.swift in Sources */,
6BEA732224ACF9FF007EA8DC /* PositionAlignment.swift in Sources */,
Expand All @@ -585,6 +593,7 @@
6BEF51A724C9ED34000DF66B /* PagerProxy.swift in Sources */,
6BCF138F24B2675000AADE74 /* ContentLoadingPolicy.swift in Sources */,
172F4D8023DF8B3800FD2F15 /* View+Helper.swift in Sources */,
6B362CC02534940B008DB2DF /* PaginationSensitivity.swift in Sources */,
172F4D8523DF8B4800FD2F15 /* Pager+Buildable.swift in Sources */,
6BEA732824ACFA04007EA8DC /* SwipeDirection.swift in Sources */,
6BEA732324ACF9FF007EA8DC /* PositionAlignment.swift in Sources */,
Expand All @@ -609,6 +618,7 @@
6BEF51A524C9ED33000DF66B /* PagerProxy.swift in Sources */,
6BCF138D24B2674F00AADE74 /* ContentLoadingPolicy.swift in Sources */,
6B2C305C248D740800E528F9 /* Buildable.swift in Sources */,
6B362CBE2534940B008DB2DF /* PaginationSensitivity.swift in Sources */,
6B2C305E248D740800E528F9 /* Pager.swift in Sources */,
6BEA732624ACFA03007EA8DC /* SwipeDirection.swift in Sources */,
6BEA732124ACF9FE007EA8DC /* PositionAlignment.swift in Sources */,
Expand All @@ -633,6 +643,7 @@
6BBC3D782488DC0E004194BD /* Pager+Buildable.swift in Sources */,
6BEF51A824C9ED35000DF66B /* PagerProxy.swift in Sources */,
6BCF139024B2675000AADE74 /* ContentLoadingPolicy.swift in Sources */,
6B362CC12534940B008DB2DF /* PaginationSensitivity.swift in Sources */,
6BBC3D742488DC01004194BD /* View+Helper.swift in Sources */,
6BEA732924ACFA04007EA8DC /* SwipeDirection.swift in Sources */,
6BEA732424ACFA00007EA8DC /* PositionAlignment.swift in Sources */,
Expand All @@ -657,6 +668,7 @@
6BEF51A424C9ED33000DF66B /* PagerProxy.swift in Sources */,
6BCF138C24B2674E00AADE74 /* ContentLoadingPolicy.swift in Sources */,
6BDE442C23DE12480022A2F7 /* Buildable.swift in Sources */,
6B362CBD2534940B008DB2DF /* PaginationSensitivity.swift in Sources */,
6BDE442923DE12480022A2F7 /* Pager.swift in Sources */,
6BEA732524ACFA02007EA8DC /* SwipeDirection.swift in Sources */,
6BEA732024ACF9FE007EA8DC /* PositionAlignment.swift in Sources */,
Expand Down
9 changes: 9 additions & 0 deletions Tests/SwiftUIPagerTests/Pager+Buildable_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,22 @@ final class Pager_Buildable_Tests: XCTestCase {
XCTAssertEqual(pager.contentLoadingPolicy, .default)
XCTAssertEqual(pager.allowsMultiplePagination, false)
XCTAssertNil(pager.pagingAnimation)
XCTAssertEqual(pager.sensitivity, .default)

let pagerContent = pager.content(for: CGSize(width: 100, height: 100))
XCTAssertNil(pagerContent.direction)
XCTAssertEqual(pagerContent.minimumDistance, 15)
XCTAssertFalse(pagerContent.isDragging)
}

func test_GivenPager_WhenSensitivityHigh_ThenSensitivityHigh() {
var pager = givenPager
pager = pager.sensitivity(.high)

let pagerContent = pager.content(for: CGSize(width: 100, height: 100))
XCTAssertEqual(pagerContent.sensitivity, .high)
}

func test_GivenPager_WhenDelaysTouchesFalse_ThenMinimumDistanceZero() {
var pager = givenPager
pager = pager.delaysTouches(false)
Expand Down
Loading

0 comments on commit 0883ceb

Please sign in to comment.