-
Notifications
You must be signed in to change notification settings - Fork 465
Expand file tree
/
Copy pathPagerView.swift
More file actions
73 lines (68 loc) · 2.58 KB
/
PagerView.swift
File metadata and controls
73 lines (68 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import SwiftUI
@_spi(Advanced) import SwiftUIIntrospect
struct PagerView: View {
@ObservedObject var props: PagerViewProps
@State private var scrollDelegate = PagerScrollDelegate()
weak var delegate: PagerViewProviderDelegate?
@Weak var collectionView: UICollectionView?
var body: some View {
TabView(selection: $props.currentPage) {
ForEach(props.children) { child in
if let index = props.children.firstIndex(of: child) {
RepresentableView(view: child.view)
.tag(index)
}
}
}
.id(props.children.count)
.background(.clear)
.tabViewStyle(.page(indexDisplayMode: .never))
.environment(\.layoutDirection, props.layoutDirection.converted)
.introspect(.tabView(style: .page), on: .iOS(.v14...)) { collectionView in
self.collectionView = collectionView
collectionView.bounces = props.overdrag
collectionView.isScrollEnabled = props.scrollEnabled
collectionView.keyboardDismissMode = props.keyboardDismissMode
collectionView.showsVerticalScrollIndicator = false
collectionView.showsHorizontalScrollIndicator = false
if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
layout.scrollDirection = props.orientation
}
if scrollDelegate.originalDelegate == nil {
scrollDelegate.originalDelegate = collectionView.delegate
scrollDelegate.delegate = delegate
scrollDelegate.orientation = props.orientation
collectionView.delegate = scrollDelegate
}
}
.onAppear {
// Apply initial prop values that .onChange won't catch
// (.onChange only fires on changes, not on initial values)
DispatchQueue.main.async {
collectionView?.isScrollEnabled = props.scrollEnabled
collectionView?.bounces = props.overdrag
}
}
.onChange(of: props.children) { newValue in
if props.currentPage >= newValue.count && !newValue.isEmpty {
props.currentPage = newValue.count - 1
}
}
.onChange(of: props.currentPage) { newValue in
if scrollDelegate.lastSelectedPage != newValue {
scrollDelegate.lastSelectedPage = newValue
scrollDelegate.isProgrammaticScroll = true
delegate?.onPageSelected(position: newValue)
}
}
.onChange(of: props.scrollEnabled) { newValue in
collectionView?.isScrollEnabled = newValue
}
.onChange(of: props.overdrag) { newValue in
collectionView?.bounces = newValue
}
.onChange(of: props.keyboardDismissMode) { newValue in
collectionView?.keyboardDismissMode = newValue
}
}
}