Skip to content

Commit

Permalink
Fix: loopPages and interactive modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
fermoya committed Mar 29, 2022
1 parent f7c28b0 commit 19159aa
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 37 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/build-legacy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ jobs:
- name: Run script
env:
DESTINATION: 'platform=iOS Simulator,name=iPhone 8,OS=12.4'
run: ./scripts/build_platforms.sh
run: |
ls /Library/Developer/CoreSimulator/Profiles/Runtimes
./scripts/build_platforms.sh
46 changes: 13 additions & 33 deletions Sources/SwiftUIPager/PagerContent+Helper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,7 @@ extension Pager.PagerContent {
/// Oppacity for each item when `faded` animation is chosen
func opacity(for item: PageWrapper<Element, ID>) -> Double {
guard let opacityIncrement = opacityIncrement else { return 1 }
guard let index: Int = dataDisplayed.firstIndex(of: item) else { return 1 }
guard let displayedItem = dataDisplayed.first(where: { $0 == data[page] }) else { return 1 }
guard let displayedIndex: Int = dataDisplayed.firstIndex(of: displayedItem) else { return 1 }
let totalIncrement = abs(totalOffset / pageDistance)
let currentIndex = direction == .forward ? CGFloat(index) - totalIncrement : CGFloat(index) + totalIncrement

let distance = abs(currentIndex - CGFloat(displayedIndex))
let distance = abs(distance(to: item))
return Double(max(0, min(1, 1 - distance * CGFloat(opacityIncrement))))
}

Expand All @@ -266,17 +260,8 @@ extension Pager.PagerContent {
/// Angle for the 3D rotation effect
func angle(for item: PageWrapper<Element, ID>) -> Angle {
guard shouldRotate else { return .zero }
guard let index = data.firstIndex(of: item) else { return .zero }

let totalIncrement = abs(totalOffset / pageDistance)

let currentAngle = Angle(degrees: Double(page - index) * rotationDegrees)
guard isDragging else {
return currentAngle
}

let newAngle = direction == .forward ? Angle(degrees: currentAngle.degrees + rotationDegrees * Double(totalIncrement)) : Angle(degrees: currentAngle.degrees - rotationDegrees * Double(totalIncrement) )
return newAngle
let distance = distance(to: item)
return Angle(degrees: rotationDegrees * Double(distance))
}

/// Axis for the rotations effect
Expand All @@ -287,24 +272,19 @@ extension Pager.PagerContent {

/// Scale that applies to a particular item
func scale(for item: PageWrapper<Element, ID>) -> CGFloat {
guard isDragging else { return isFocused(item) ? 1 : interactiveScale }

let totalIncrement = abs(totalOffset / pageDistance)
let currentPage = direction == .forward ? CGFloat(page) + totalIncrement : CGFloat(page) - totalIncrement

guard let indexInt = data.firstIndex(of: item) else { return interactiveScale }
let distance = abs(distance(to: item))
return Double(max(interactiveScale, min(1, 1 - distance * scaleIncrement)))
}

let index = CGFloat(indexInt)
guard abs(currentPage - index) <= 1 else { return interactiveScale }
private func distance(to item: PageWrapper<Element, ID>) -> CGFloat {
guard let index: Int = dataDisplayed.firstIndex(of: item) else { return 0 }
guard let displayedItem = dataDisplayed.first(where: { $0 == data[page] }) else { return 0 }
guard let displayedIndex: Int = dataDisplayed.firstIndex(of: displayedItem) else { return 0 }

let increment = totalIncrement - totalIncrement.rounded(.towardZero)
let nextPage = direction == .forward ? currentPage.rounded(.awayFromZero) : currentPage.rounded(.towardZero)
guard currentPage > 0 else {
return 1 - (scaleIncrement * increment)
}
let totalIncrement = abs(totalOffset / pageDistance)
let currentIndex = direction == .forward ? CGFloat(index) - totalIncrement : CGFloat(index) + totalIncrement

return index == nextPage ? interactiveScale + (scaleIncrement * increment)
: 1 - (scaleIncrement * increment)
return CGFloat(displayedIndex) - currentIndex
}

/// Returns true if the item is focused on the screen.
Expand Down
4 changes: 2 additions & 2 deletions Tests/SwiftUIPagerTests/PagerContent+Helper_Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,12 @@ final class PagerContent_Helper_Tests: XCTestCase {
let pager = givenPager.interactive(scale: 0.7).pageOffset(0.1)
let item = PageWrapper(batchId: 1, keyPath: \.self, element: 200)
let scale = pager.scale(for: item)
XCTAssertEqual(scale, 0.7)
XCTAssertEqual(scale, 1)
}

func test_GivenPagerDragging_WhenScaleForFarItem_ThenInteractiveScale() {
let pager = givenPager.interactive(scale: 0.7).pageOffset(-0.1)
let item = PageWrapper(batchId: 1, keyPath: \.self, element: 3)
let item = PageWrapper(batchId: 1, keyPath: \.self, element: 2)
let scale = pager.scale(for: item)
XCTAssertEqual(scale, 0.7)
}
Expand Down
3 changes: 2 additions & 1 deletion release_description.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
### Fixes
- #244 `loopPages` fail to use right `page` if `repeating` elements
- #253 #233 `loopPages` fades pages
- #252 `NavigationView` swipe gestures not working if wrapping a `Pager`
- #252 `NavigationView` swipe gestures not working if wrapping a `Pager`
- #259 `loopPages` not working well with `interactive` approaches

0 comments on commit 19159aa

Please sign in to comment.