Skip to content

Commit

Permalink
Merge pull request #4 from fermoya/fix/page-offset
Browse files Browse the repository at this point in the history
Fix/page offset
  • Loading branch information
fermoya authored Jan 23, 2020
2 parents 1689bf1 + ddea9f8 commit 0a1109a
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 69 deletions.
16 changes: 8 additions & 8 deletions Sample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
17D9E0FA23D4CF6900C5AE93 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 17D9E0F923D4CF6900C5AE93 /* Assets.xcassets */; };
17D9E0FD23D4CF6900C5AE93 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 17D9E0FC23D4CF6900C5AE93 /* Assets.xcassets */; };
17D9E10023D4CF6900C5AE93 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 17D9E0FE23D4CF6900C5AE93 /* LaunchScreen.storyboard */; };
6B3489BC23D85D46002601D8 /* SwiftUIPager in Frameworks */ = {isa = PBXBuildFile; productRef = 6B3489BB23D85D46002601D8 /* SwiftUIPager */; };
6BB892E023D9F13C00AC9331 /* SwiftUIPager in Frameworks */ = {isa = PBXBuildFile; productRef = 6BB892DF23D9F13C00AC9331 /* SwiftUIPager */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand All @@ -32,7 +32,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
6B3489BC23D85D46002601D8 /* SwiftUIPager in Frameworks */,
6BB892E023D9F13C00AC9331 /* SwiftUIPager in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -94,7 +94,7 @@
);
name = Sample;
packageProductDependencies = (
6B3489BB23D85D46002601D8 /* SwiftUIPager */,
6BB892DF23D9F13C00AC9331 /* SwiftUIPager */,
);
productName = SwiftUIPager;
productReference = 17D9E0F023D4CF6700C5AE93 /* Sample.app */;
Expand Down Expand Up @@ -125,7 +125,7 @@
);
mainGroup = 17D9E0E723D4CF6700C5AE93;
packageReferences = (
6B3489BA23D85D46002601D8 /* XCRemoteSwiftPackageReference "SwiftUIPager" */,
6BB892DE23D9F13C00AC9331 /* XCRemoteSwiftPackageReference "SwiftUIPager" */,
);
productRefGroup = 17D9E0F123D4CF6700C5AE93 /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -352,20 +352,20 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
6B3489BA23D85D46002601D8 /* XCRemoteSwiftPackageReference "SwiftUIPager" */ = {
6BB892DE23D9F13C00AC9331 /* XCRemoteSwiftPackageReference "SwiftUIPager" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/fermoya/SwiftUIPager";
requirement = {
branch = "feat/vertical-pagintation";
branch = "fix/page-offset";
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
6B3489BB23D85D46002601D8 /* SwiftUIPager */ = {
6BB892DF23D9F13C00AC9331 /* SwiftUIPager */ = {
isa = XCSwiftPackageProductDependency;
package = 6B3489BA23D85D46002601D8 /* XCRemoteSwiftPackageReference "SwiftUIPager" */;
package = 6BB892DE23D9F13C00AC9331 /* XCRemoteSwiftPackageReference "SwiftUIPager" */;
productName = SwiftUIPager;
};
/* End XCSwiftPackageProductDependency section */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"package": "SwiftUIPager",
"repositoryURL": "https://github.com/fermoya/SwiftUIPager",
"state": {
"branch": "feat/vertical-pagintation",
"revision": "824efeeaac08717ef7d1aefc5037c3e3f32736e6",
"branch": "fix/page-offset",
"revision": "3b05829020ec5e10a0997455b2a7fb18dfb4af53",
"version": null
}
}
Expand Down
60 changes: 37 additions & 23 deletions Sample/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,48 @@ extension Int: Identifiable {
}

struct ContentView: View {


@State var isPresented: Bool = false
@State var pageIndex: Int = 0
var data: [Int] = Array((0...20))

var body: some View {
Button(action: {
self.isPresented.toggle()
}, label: {
Text("Tap me")
}).sheet(isPresented: $isPresented, content: {
self.presentedView
})
}

var presentedView: some View {
GeometryReader { proxy in
VStack {
Pager(page: self.$pageIndex,
data: self.data,
content: { index in
self.pageView(index)
.cornerRadius(10)
.shadow(radius: 5)
})
.interactive(0.8)
.itemSpacing(10)
.padding(8)
.itemAspectRatio(1.5)
.vertical()
.border(Color.red, width: 2)
.frame(width: min(proxy.size.width,
proxy.size.height),
height: min(proxy.size.width,
proxy.size.height))
Spacer()
Text("Page: \(self.pageIndex)")
.bold()
Spacer()
ScrollView {
VStack {
Pager(page: self.$pageIndex,
data: self.data,
content: { index in
self.pageView(index)
.cornerRadius(10)
.shadow(radius: 5)
})
.interactive(0.8)
.itemSpacing(10)
.padding(8)
.itemAspectRatio(0.8)
.itemTappable(true)
.frame(width: min(proxy.size.width,
proxy.size.height),
height: min(proxy.size.width,
proxy.size.height))
.border(Color.red, width: 2)
ForEach(self.data) { i in
Text("Page: \(i)")
.bold()
.padding()
}
}
}
}
}
Expand Down
18 changes: 4 additions & 14 deletions Sources/SwiftUIPager/Helpers/SizeViewModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,6 @@

import SwiftUI

/// Tracks the size of the view
struct SizePreferenceKey: PreferenceKey {
static var defaultValue: CGSize = .zero

static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
value = nextValue()
}
}

/// This modifier wraps a view into a `GeometryReader` and tracks the available space by using `SizePreferenceKey` on the content
struct SizeViewModifier: ViewModifier {

Expand All @@ -25,12 +16,11 @@ struct SizeViewModifier: ViewModifier {
func body(content: Content) -> some View {
GeometryReader { proxy in
content
.preference(key: SizePreferenceKey.self,
value: proxy.size)
.frame(width: proxy.size.width, height: proxy.size.height)
.onAppear (perform: {
self.size = proxy.size
})
}
.onPreferenceChange(SizePreferenceKey.self, perform: { (newSize) in
self.size = newSize
})
.clipped()
}
}
Expand Down
12 changes: 8 additions & 4 deletions Sources/SwiftUIPager/Pager+Buildable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import SwiftUI

extension Pager: Buildable {

/// Adds a `TapGesture` to the items to bring them to focus
public func itemTappable(_ value: Bool) -> Self {
mutating(keyPath: \.isItemTappable, value: value)
}

/// Returns a horizontal pager
public func horizontal() -> Self {
mutating(keyPath: \.isHorizontal, value: true)
Expand Down Expand Up @@ -39,10 +44,9 @@ extension Pager: Buildable {
.mutating(keyPath: \.shouldRotate, value: value)
}

/// Provides an offset to modify the
public func contentOffset(_ pageOffset: Double) -> Self {
let contentOffset = CGFloat(pageOffset) * pageDistance
return mutating(keyPath: \.contentOffset, value: contentOffset)
/// Provides an increment to the page index offset. Use this to modify the scroll offset
public func pageOffset(_ pageOffset: Double) -> Self {
mutating(keyPath: \.pageOffset, value: pageOffset)
}

/// Adds space between each page
Expand Down
15 changes: 10 additions & 5 deletions Sources/SwiftUIPager/Pager+Helper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ extension Pager {
return !isHorizontal
}

/// `pageOffset` converted to scrollable offset
var contentOffset: CGFloat {
-CGFloat(pageOffset) * pageDistance
}

/// Size increment to be applied to a unfocs item when it comes to focus
var scaleIncrement: CGFloat { 1 - interactiveScale }

Expand Down Expand Up @@ -88,7 +93,7 @@ extension Pager {
}

/// Data that is being displayed at the moment
var dataDisplayed: [Data] {
var dataDisplayed: [Element] {
Array(data[lowerPageDisplayed..<upperPageDisplayed])
}

Expand All @@ -112,7 +117,7 @@ extension Pager {
}

/// Angle for the 3D rotation effect
func angle(for item: Data) -> Angle {
func angle(for item: Element) -> Angle {
guard shouldRotate else { return .zero }
guard let index = data.firstIndex(of: item) else { return .zero }

Expand All @@ -128,7 +133,7 @@ extension Pager {
}

/// Axis for the rotations effect
func axis(for item: Data) -> (CGFloat, CGFloat, CGFloat) {
func axis(for item: Element) -> (CGFloat, CGFloat, CGFloat) {
guard shouldRotate else { return (0, 0, 0) }
guard let index = data.firstIndex(of: item) else { return (0, 0, 0) }

Expand All @@ -137,7 +142,7 @@ extension Pager {
}

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

let totalIncrement = abs(totalOffset / pageDistance)
Expand All @@ -159,7 +164,7 @@ extension Pager {
}

/// Returns true if the item is focused on the screen.
func isFocused(_ item: Data) -> Bool {
func isFocused(_ item: Element) -> Bool {
data.firstIndex(of: item) == currentPage
}

Expand Down
34 changes: 22 additions & 12 deletions Sources/SwiftUIPager/Pager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import SwiftUI
/// - 30 px of vertical insets
/// - 0.6 shrink ratio for items that aren't focused.
///
public struct Pager<Data, Content>: View where Content: View, Data: Identifiable & Equatable {
public struct Pager<Element, PageView>: View where PageView: View, Element: Identifiable & Equatable {

/// `Direction` determines the direction of the swipe gesture
enum Direction {
Expand Down Expand Up @@ -58,13 +58,17 @@ public struct Pager<Data, Content>: View where Content: View, Data: Identifiabl
/*** Dependencies ***/

/// `ViewBuilder` block to create each page
let content: (Data) -> Content
let content: (Element) -> PageView

/// Array of items that will populate each page
var data: [Data]
var data: [Element]

/*** ViewModified properties ***/

/// `true` if items are tapable
var isItemTappable: Bool = false

/// `true` if the pager is horizontal
var isHorizontal: Bool = true

/// Shrink ratio that affects the items that aren't focused
Expand All @@ -74,7 +78,7 @@ public struct Pager<Data, Content>: View where Content: View, Data: Identifiabl
var shouldRotate: Bool = false

/// Used to modify `Pager` offset outside this view
var contentOffset: CGFloat = 0
var pageOffset: Double = 0

/// Vertical padding
var sideInsets: CGFloat = 0
Expand Down Expand Up @@ -111,12 +115,12 @@ public struct Pager<Data, Content>: View where Content: View, Data: Identifiabl
/// - Parameter page: Binding to the index of the focused page
/// - Parameter data: Array of items to populate the content
/// - Parameter content: Factory method to build new pages
public init(page: Binding<Int>, data: [Data], @ViewBuilder content: @escaping (Data) -> Content) {
public init(page: Binding<Int>, data: [Element], @ViewBuilder content: @escaping (Element) -> PageView) {
self._page = page
self.data = data
self.content = content
}

public var body: some View {
HStack(spacing: self.interactiveItemSpacing) {
ForEach(self.dataDisplayed) { item in
Expand All @@ -127,11 +131,8 @@ public struct Pager<Data, Content>: View where Content: View, Data: Identifiabl
axis: (0, 0, 1))
.rotation3DEffect(self.angle(for: item),
axis: self.axis(for: item))
.onTapGesture (perform: {
withAnimation(.spring()) {
self.scrollToItem(item)
}
})
.gesture(self.tapGesture(for: item))
.disabled(self.isFocused(item) || !self.isItemTappable)
}
.offset(x: self.xOffset, y : 0)
}
Expand All @@ -147,11 +148,20 @@ public struct Pager<Data, Content>: View where Content: View, Data: Identifiabl
extension Pager {

/// Helper function to scroll to a specific item.
func scrollToItem(_ item: Data) {
func scrollToItem(_ item: Element) {
guard let index = data.firstIndex(of: item) else { return }
self.page = index
}

func tapGesture(for item: Element) -> some Gesture {
TapGesture(count: 1)
.onEnded({ _ in
withAnimation(.spring()) {
self.scrollToItem(item)
}
})
}

/// `DragGesture` customized to work with `Pager`
var swipeGesture: some Gesture {
DragGesture()
Expand Down
2 changes: 1 addition & 1 deletion SwiftUIPager.podspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|

s.name = "SwiftUIPager"
s.version = "1.1.0"
s.version = "1.1.1"
s.summary = "Native pager for SwiftUI. Easily to use, easy to customize."

s.description = <<-DESC
Expand Down

0 comments on commit 0a1109a

Please sign in to comment.