Position Scroll View is pure Swift UI Scroll View which can get or move scroll position.
- Get scroll position of scroll
- Vertical, Horizontal, Two Dimensional scroll
- Move scroll position by code
- Stick edge of scroll page or follow momentum after scroll ends.
- Xcode 11.6+
- Swift 5.2+
Add https://github.com/kazuooooo/PositionScrollView
in the Swit Package Magener tab in Xcode
pod ‘PositionScrollView’
PositionScrollView divides whole target view to pages and units to treat scroll position easily.
And you can get/set position in each ranges.
Minimal horizontal scroll view example below.
import Foundation
import SwiftUI
import PositionScrollView
/// Extended ScrollView which can controll position
public struct MinimalHorizontalExample: View, PositionScrollViewDelegate {
/// Page size of Scroll
var pageSize = CGSize(width: 200, height: 300)
// Create PositionScrollViewModel
// (Need to create in parent view to bind the state between this view and PositionScrollView)
@ObservedObject var psViewModel = PositionScrollViewModel(
pageSize: CGSize(width: 200, height: 300),
horizontalScroll: Scroll(
scrollSetting: ScrollSetting(pageCount: 5, afterMoveType: .fitToNearestUnit),
pageLength: 200
)
)
public var body: some View {
return VStack {
PositionScrollView(
viewModel: self.psViewModel,
delegate: self
) {
HStack(spacing: 0) {
ForEach(0...4, id: \.self){ i in
ZStack {
Rectangle()
.fill(Color.gray)
.border(Color.white)
.frame(
width: self.pageSize.width, height: self.pageSize.height
)
Text("Page\(i)")
.foregroundColor(Color.white)
.font(.system(size: 24, weight: .heavy, design: .default))
}
}
}
}
Text("page: \(self.psViewModel.horizontalScroll?.page ?? 0)")
Text("position: \(self.psViewModel.horizontalScroll?.position ?? 0)")
}
}
struct SampleView_Previews: PreviewProvider {
static var previews: some View {
return MinimalHorizontalExample()
}
}
// Delegate methods of PositionScrollView
public func onScrollStart() {
print("onScrollStart")
}
public func onChangePage(page: Int) {
print("onChangePage to page: \(page)")
}
public func onChangePosition(position: CGFloat) {
print("position: \(position)")
}
public func onScrollEnd() {
print("onScrollEnd")
}
}
Setting variables
ValueName | Type | Default | Detail |
---|---|---|---|
pageCount* | Int | - | Count of page |
initialPage | Int | 0 | Initial page of scroll |
unitCountInPage | Int | 1 | Unit count of single page |
afterMoveType | AfterScrollEndsBehavior | .stickToNearestUnitEdge | Behavior of scroll move after scroll ends stickToNearestUnitEdge: Stick nearest unit edge momentum: It move until momentum disappear. |
scrollSpeedToDetect | Double | 30 | Scroll speed to detect |
Variables
ValueName | Type | Detail |
---|---|---|
position | CGFloat | Position based on the start of page 0 |
page | Int | Current page |
positionInPage | CGFloat | Current position based on the start of the page |
unit | Int | Current unit in page |
positionInUnit | CGFloat | Current position based on the start of the unit |
Functions
FunctionName | Args | Detail |
---|---|---|
moveBy | value: CGFloat | Move scroll by argment value |
moveTo | position: CGFloat | Move scroll to argment position |
moveToPage | page: Int unit: Int = 0 positionInUnit: CGFloat = 0 |
Move scroll to argument page |
FunctionName | Args | Detail |
---|---|---|
onScrollStart | - | Called when a scroll starts |
onChangePosition | position: CGFloat | Called when position changed |
onChangePage | page: Int | Called when scroll page changed |
onChangeUnit | unit: Int | Called when unit changed |
onChangePositionInPage | positionInPage: CGFloat | Called when position in page changed |
onChangePositionInUnit | positionInUnit: CGFloat | Called when position in unit changed |
onScrollEnd | - | Called when a scroll ends |
Please feel free to contact me. kazuooooo