@lodev09/react-native-true-sheet 3.8.0-beta.0 → 3.8.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,7 +37,7 @@ class TrueSheetContainerView(reactContext: ThemedReactContext) :
37
37
 
38
38
  var insetAdjustment: String = "automatic"
39
39
  var scrollViewBottomInset: Int = 0
40
- var scrollViewPinningEnabled: Boolean = false
40
+ var scrollableEnabled: Boolean = false
41
41
  var scrollableOptions: ReadableMap? = null
42
42
  set(value) {
43
43
  field = value
@@ -53,9 +53,9 @@ class TrueSheetContainerView(reactContext: ThemedReactContext) :
53
53
  clipToPadding = false
54
54
  }
55
55
 
56
- fun setupContentScrollViewPinning() {
56
+ fun setupScrollable() {
57
57
  val bottomInset = if (insetAdjustment == "automatic") scrollViewBottomInset else 0
58
- contentView?.setupScrollViewPinning(scrollViewPinningEnabled, bottomInset)
58
+ contentView?.setupScrollable(scrollableEnabled, bottomInset)
59
59
  }
60
60
 
61
61
  fun setupKeyboardHandler() {
@@ -52,9 +52,9 @@ class TrueSheetContentView(private val reactContext: ThemedReactContext) : React
52
52
  }
53
53
  }
54
54
 
55
- fun setupScrollViewPinning(enabled: Boolean, bottomInset: Int) {
55
+ fun setupScrollable(enabled: Boolean, bottomInset: Int) {
56
56
  if (!enabled) {
57
- clearScrollViewPinning()
57
+ clearScrollable()
58
58
  return
59
59
  }
60
60
 
@@ -89,7 +89,7 @@ class TrueSheetContentView(private val reactContext: ThemedReactContext) : React
89
89
  }
90
90
  }
91
91
 
92
- fun clearScrollViewPinning() {
92
+ fun clearScrollable() {
93
93
  pinnedScrollView?.setPadding(
94
94
  pinnedScrollView!!.paddingLeft,
95
95
  pinnedScrollView!!.paddingTop,
@@ -120,7 +120,7 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
120
120
  if (child is TrueSheetContainerView) {
121
121
  child.delegate = this
122
122
  viewController.createSheet()
123
- setupContentScrollViewPinning()
123
+ setupScrollable()
124
124
 
125
125
  val surfaceId = UIManagerHelper.getSurfaceId(this)
126
126
  eventDispatcher?.dispatchEvent(MountEvent(surfaceId, id))
@@ -186,7 +186,7 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
186
186
  * Reconfigures the sheet if it's currently presented.
187
187
  */
188
188
  fun finalizeUpdates() {
189
- setupContentScrollViewPinning()
189
+ setupScrollable()
190
190
 
191
191
  if (viewController.isPresented) {
192
192
  viewController.sheetView?.setupBackground()
@@ -256,26 +256,26 @@ class TrueSheetView(private val reactContext: ThemedReactContext) :
256
256
 
257
257
  fun setInsetAdjustment(insetAdjustment: String) {
258
258
  viewController.insetAdjustment = insetAdjustment
259
- setupContentScrollViewPinning()
259
+ setupScrollable()
260
260
  }
261
261
 
262
262
  fun setScrollable(scrollable: Boolean) {
263
263
  viewController.scrollable = scrollable
264
- setupContentScrollViewPinning()
264
+ setupScrollable()
265
265
  }
266
266
 
267
267
  fun setScrollableOptions(options: ReadableMap?) {
268
268
  viewController.scrollableOptions = options
269
- setupContentScrollViewPinning()
269
+ setupScrollable()
270
270
  }
271
271
 
272
- private fun setupContentScrollViewPinning() {
272
+ private fun setupScrollable() {
273
273
  viewController.containerView?.let {
274
274
  it.insetAdjustment = viewController.insetAdjustment
275
- it.scrollViewPinningEnabled = viewController.scrollable
275
+ it.scrollableEnabled = viewController.scrollable
276
276
  it.scrollViewBottomInset = viewController.contentBottomInset
277
277
  it.scrollableOptions = viewController.scrollableOptions
278
- it.setupContentScrollViewPinning()
278
+ it.setupScrollable()
279
279
  }
280
280
  }
281
281
 
@@ -39,12 +39,12 @@ NS_ASSUME_NONNULL_BEGIN
39
39
  @property (nonatomic, weak, nullable) id<TrueSheetContainerViewDelegate> delegate;
40
40
 
41
41
  /**
42
- * Enable ScrollView pinning
42
+ * Enable scrollable content
43
43
  */
44
- @property (nonatomic, assign) BOOL scrollViewPinningEnabled;
44
+ @property (nonatomic, assign) BOOL scrollableEnabled;
45
45
 
46
46
  /**
47
- * Inset adjustment mode for pinned ScrollView
47
+ * Inset adjustment mode for scrollable content
48
48
  */
49
49
  @property (nonatomic, copy, nullable) NSString *insetAdjustment;
50
50
 
@@ -69,9 +69,9 @@ NS_ASSUME_NONNULL_BEGIN
69
69
  - (void)layoutFooter;
70
70
 
71
71
  /**
72
- * Setup ScrollView pinning
72
+ * Setup scrollable content
73
73
  */
74
- - (void)setupContentScrollViewPinning;
74
+ - (void)setupScrollable;
75
75
 
76
76
  /**
77
77
  * Setup keyboard observer for content and footer
@@ -34,7 +34,7 @@ using namespace facebook::react;
34
34
  TrueSheetHeaderView *_headerView;
35
35
  TrueSheetFooterView *_footerView;
36
36
  TrueSheetKeyboardObserver *_keyboardObserver;
37
- BOOL _scrollViewPinningSet;
37
+ BOOL _scrollableSet;
38
38
  }
39
39
 
40
40
  #pragma mark - Initialization
@@ -52,13 +52,18 @@ using namespace facebook::react;
52
52
  _contentView = nil;
53
53
  _headerView = nil;
54
54
  _footerView = nil;
55
- _scrollViewPinningSet = NO;
55
+ _scrollableSet = NO;
56
56
  }
57
57
  return self;
58
58
  }
59
59
 
60
60
  #pragma mark - Layout
61
61
 
62
+ - (void)layoutSubviews {
63
+ [super layoutSubviews];
64
+ [_contentView updateScrollViewHeight];
65
+ }
66
+
62
67
  - (CGFloat)contentHeight {
63
68
  return _contentView ? _contentView.frame.size.height : 0;
64
69
  }
@@ -76,9 +81,9 @@ using namespace facebook::react;
76
81
  }
77
82
  }
78
83
 
79
- - (void)setScrollViewPinningEnabled:(BOOL)scrollViewPinningEnabled {
80
- _scrollViewPinningEnabled = scrollViewPinningEnabled;
81
- _scrollViewPinningSet = YES;
84
+ - (void)setScrollableEnabled:(BOOL)scrollableEnabled {
85
+ _scrollableEnabled = scrollableEnabled;
86
+ _scrollableSet = YES;
82
87
  }
83
88
 
84
89
  - (void)setScrollableOptions:(NSDictionary *)scrollableOptions {
@@ -91,13 +96,13 @@ using namespace facebook::react;
91
96
  }
92
97
  }
93
98
 
94
- - (void)setupContentScrollViewPinning {
95
- if (_scrollViewPinningSet && _contentView) {
99
+ - (void)setupScrollable {
100
+ if (_scrollableSet && _contentView) {
96
101
  CGFloat bottomInset = 0;
97
102
  if ([_insetAdjustment isEqualToString:@"automatic"]) {
98
103
  bottomInset = [WindowUtil keyWindow].safeAreaInsets.bottom;
99
104
  }
100
- [_contentView setupScrollViewPinning:_scrollViewPinningEnabled bottomInset:bottomInset];
105
+ [_contentView setupScrollable:_scrollableEnabled bottomInset:bottomInset];
101
106
  }
102
107
  }
103
108
 
@@ -164,11 +169,7 @@ using namespace facebook::react;
164
169
  }
165
170
 
166
171
  - (void)contentViewDidChangeChildren {
167
- [self setupContentScrollViewPinning];
168
- }
169
-
170
- - (void)contentViewDidChangeInsets {
171
- [self setupContentScrollViewPinning];
172
+ [self setupScrollable];
172
173
  }
173
174
 
174
175
  #pragma mark - TrueSheetHeaderViewDelegate
@@ -23,7 +23,6 @@ NS_ASSUME_NONNULL_BEGIN
23
23
 
24
24
  - (void)contentViewDidChangeSize:(CGSize)newSize;
25
25
  - (void)contentViewDidChangeChildren;
26
- - (void)contentViewDidChangeInsets;
27
26
 
28
27
  @end
29
28
 
@@ -33,14 +32,19 @@ NS_ASSUME_NONNULL_BEGIN
33
32
  @property (nonatomic, assign) CGFloat keyboardScrollOffset;
34
33
  @property (nonatomic, weak, nullable) TrueSheetKeyboardObserver *keyboardObserver;
35
34
 
36
- - (RCTScrollViewComponentView *_Nullable)findScrollView:(UIView *_Nullable *_Nullable)outTopSibling;
35
+ - (RCTScrollViewComponentView *_Nullable)findScrollView;
37
36
 
38
37
  /**
39
- * Setup ScrollView pinning
40
- * @param pinned Whether to pin the scroll view
38
+ * Setup scrollable content
39
+ * @param enabled Whether scrollable is enabled
41
40
  * @param bottomInset Bottom content inset for the scroll view
42
41
  */
43
- - (void)setupScrollViewPinning:(BOOL)pinned bottomInset:(CGFloat)bottomInset;
42
+ - (void)setupScrollable:(BOOL)enabled bottomInset:(CGFloat)bottomInset;
43
+
44
+ /**
45
+ * Update the pinned scroll view's height to fill the container
46
+ */
47
+ - (void)updateScrollViewHeight;
44
48
 
45
49
  @end
46
50
 
@@ -16,20 +16,16 @@
16
16
  #import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
17
17
  #import "TrueSheetView.h"
18
18
  #import "TrueSheetViewController.h"
19
- #import "utils/LayoutUtil.h"
20
19
  #import "utils/UIView+FirstResponder.h"
21
20
 
22
21
  using namespace facebook::react;
23
22
 
24
23
  @implementation TrueSheetContentView {
25
24
  RCTScrollViewComponentView *_pinnedScrollView;
26
- UIView *_pinnedTopView;
27
25
  CGSize _lastSize;
28
- UIEdgeInsets _contentInsets;
29
- UIEdgeInsets _pinnedInsets;
30
26
  CGFloat _bottomInset;
27
+ CGFloat _originalScrollViewHeight;
31
28
  CGFloat _originalIndicatorBottomInset;
32
- CGFloat _currentKeyboardHeight;
33
29
  }
34
30
 
35
31
  + (ComponentDescriptorProvider)componentDescriptorProvider {
@@ -50,14 +46,6 @@ using namespace facebook::react;
50
46
  oldLayoutMetrics:(const LayoutMetrics &)oldLayoutMetrics {
51
47
  [super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
52
48
 
53
- UIEdgeInsets newInsets = UIEdgeInsetsMake(layoutMetrics.contentInsets.top, layoutMetrics.contentInsets.left,
54
- layoutMetrics.contentInsets.bottom, layoutMetrics.contentInsets.right);
55
-
56
- if (!UIEdgeInsetsEqualToEdgeInsets(newInsets, _contentInsets)) {
57
- _contentInsets = newInsets;
58
- [self.delegate contentViewDidChangeInsets];
59
- }
60
-
61
49
  CGSize newSize = CGSizeMake(layoutMetrics.frame.size.width, layoutMetrics.frame.size.height);
62
50
  if (!CGSizeEqualToSize(newSize, _lastSize)) {
63
51
  _lastSize = newSize;
@@ -77,12 +65,13 @@ using namespace facebook::react;
77
65
  [self.delegate contentViewDidChangeChildren];
78
66
  }
79
67
 
80
- #pragma mark - ScrollView Pinning
68
+ #pragma mark - Scrollable
81
69
 
82
- - (void)clearPinning {
70
+ - (void)clearScrollable {
83
71
  if (_pinnedScrollView) {
84
- [LayoutUtil unpinView:_pinnedScrollView fromParentView:self];
85
- [LayoutUtil unpinView:_pinnedScrollView fromParentView:self.superview];
72
+ CGRect frame = _pinnedScrollView.frame;
73
+ frame.size.height = _originalScrollViewHeight;
74
+ _pinnedScrollView.frame = frame;
86
75
 
87
76
  UIEdgeInsets contentInset = _pinnedScrollView.scrollView.contentInset;
88
77
  contentInset.bottom = 0;
@@ -93,70 +82,73 @@ using namespace facebook::react;
93
82
  _pinnedScrollView.scrollView.verticalScrollIndicatorInsets = indicatorInsets;
94
83
  }
95
84
  _pinnedScrollView = nil;
96
- _pinnedTopView = nil;
97
- _pinnedInsets = UIEdgeInsetsZero;
98
85
  _bottomInset = 0;
86
+ _originalScrollViewHeight = 0;
99
87
  _originalIndicatorBottomInset = 0;
100
88
  }
101
89
 
102
- - (void)setupScrollViewPinning:(BOOL)pinned bottomInset:(CGFloat)bottomInset {
103
- UIView *containerView = self.superview;
90
+ - (void)setupScrollable:(BOOL)enabled bottomInset:(CGFloat)bottomInset {
91
+ if (!enabled) {
92
+ [self clearScrollable];
93
+ return;
94
+ }
104
95
 
105
- if (!pinned) {
106
- [self clearPinning];
96
+ // Already set up with same inset
97
+ if (_pinnedScrollView && _bottomInset == bottomInset) {
107
98
  return;
108
99
  }
109
100
 
110
- UIView *topSibling = nil;
111
- RCTScrollViewComponentView *scrollView = [self findScrollView:&topSibling];
112
-
113
- BOOL needsUpdate = scrollView != _pinnedScrollView || topSibling != _pinnedTopView ||
114
- !UIEdgeInsetsEqualToEdgeInsets(_contentInsets, _pinnedInsets) || _bottomInset != bottomInset;
115
-
116
- if (scrollView && containerView && needsUpdate) {
117
- [self clearPinning];
118
-
119
- UIEdgeInsets insets =
120
- UIEdgeInsetsMake(topSibling ? 0 : _contentInsets.top, _contentInsets.left, 0, _contentInsets.right);
121
-
122
- if (topSibling) {
123
- [LayoutUtil pinView:scrollView
124
- toParentView:self
125
- withTopView:topSibling
126
- edges:UIRectEdgeLeft | UIRectEdgeRight
127
- insets:insets];
128
- } else {
129
- [LayoutUtil pinView:scrollView
130
- toParentView:self
131
- edges:UIRectEdgeTop | UIRectEdgeLeft | UIRectEdgeRight
132
- insets:insets];
133
- }
101
+ RCTScrollViewComponentView *scrollView = [self findScrollView];
102
+ if (!scrollView) {
103
+ return;
104
+ }
105
+
106
+ // Only capture originals on first pin
107
+ if (!_pinnedScrollView) {
108
+ _originalScrollViewHeight = scrollView.frame.size.height;
109
+ _originalIndicatorBottomInset = scrollView.scrollView.verticalScrollIndicatorInsets.bottom;
110
+ _pinnedScrollView = scrollView;
111
+ }
134
112
 
135
- [LayoutUtil pinView:scrollView toParentView:containerView edges:UIRectEdgeBottom];
113
+ _bottomInset = bottomInset;
136
114
 
137
- BOOL isNewScrollView = scrollView != _pinnedScrollView;
138
- if (isNewScrollView) {
139
- _originalIndicatorBottomInset = scrollView.scrollView.verticalScrollIndicatorInsets.bottom;
140
- }
115
+ [self updateScrollViewHeight];
141
116
 
142
- _pinnedScrollView = scrollView;
143
- _pinnedTopView = topSibling;
144
- _pinnedInsets = _contentInsets;
145
- _bottomInset = bottomInset;
146
-
147
- UIEdgeInsets contentInset = scrollView.scrollView.contentInset;
148
- contentInset.bottom = bottomInset;
149
- scrollView.scrollView.contentInset = contentInset;
150
-
151
- UIEdgeInsets indicatorInsets = scrollView.scrollView.verticalScrollIndicatorInsets;
152
- indicatorInsets.bottom = _originalIndicatorBottomInset + bottomInset;
153
- scrollView.scrollView.verticalScrollIndicatorInsets = indicatorInsets;
154
- } else if (!scrollView && _pinnedScrollView) {
155
- [self clearPinning];
117
+ UIEdgeInsets contentInset = scrollView.scrollView.contentInset;
118
+ contentInset.bottom = bottomInset;
119
+ scrollView.scrollView.contentInset = contentInset;
120
+
121
+ UIEdgeInsets indicatorInsets = scrollView.scrollView.verticalScrollIndicatorInsets;
122
+ indicatorInsets.bottom = _originalIndicatorBottomInset + bottomInset;
123
+ scrollView.scrollView.verticalScrollIndicatorInsets = indicatorInsets;
124
+ }
125
+
126
+ - (void)updateScrollViewHeight {
127
+ if (!_pinnedScrollView) {
128
+ return;
129
+ }
130
+
131
+ UIView *containerView = self.superview;
132
+ if (!containerView) {
133
+ return;
134
+ }
135
+
136
+ CGRect scrollViewFrameInContainer = [_pinnedScrollView.superview convertRect:_pinnedScrollView.frame
137
+ toView:containerView];
138
+ CGFloat newHeight = containerView.bounds.size.height - scrollViewFrameInContainer.origin.y;
139
+
140
+ if (newHeight > 0) {
141
+ CGRect frame = _pinnedScrollView.frame;
142
+ frame.size.height = newHeight;
143
+ _pinnedScrollView.frame = frame;
156
144
  }
157
145
  }
158
146
 
159
- - (RCTScrollViewComponentView *)findScrollView:(UIView **)outTopSibling {
147
+ - (RCTScrollViewComponentView *)findScrollView {
148
+ if (_pinnedScrollView) {
149
+ return _pinnedScrollView;
150
+ }
151
+
160
152
  if (self.subviews.count == 0) {
161
153
  return nil;
162
154
  }
@@ -172,10 +164,6 @@ using namespace facebook::react;
172
164
  }
173
165
  }
174
166
 
175
- if (outTopSibling) {
176
- *outTopSibling = [self findTopSiblingForScrollView:scrollView];
177
- }
178
-
179
167
  return scrollView;
180
168
  }
181
169
 
@@ -188,33 +176,6 @@ using namespace facebook::react;
188
176
  return nil;
189
177
  }
190
178
 
191
- - (UIView *)findTopSiblingForScrollView:(RCTScrollViewComponentView *)scrollView {
192
- if (!scrollView || scrollView.superview != self || self.subviews.count <= 1) {
193
- return nil;
194
- }
195
-
196
- CGFloat scrollViewTop = CGRectGetMinY(scrollView.frame);
197
- UIView *topSibling = nil;
198
- CGFloat closestDistance = CGFLOAT_MAX;
199
-
200
- for (UIView *sibling in self.subviews) {
201
- if (sibling == scrollView || [sibling isKindOfClass:TrueSheetView.class]) {
202
- continue;
203
- }
204
-
205
- CGFloat siblingBottom = CGRectGetMaxY(sibling.frame);
206
- if (siblingBottom <= scrollViewTop) {
207
- CGFloat distance = scrollViewTop - siblingBottom;
208
- if (distance < closestDistance) {
209
- closestDistance = distance;
210
- topSibling = sibling;
211
- }
212
- }
213
- }
214
-
215
- return topSibling;
216
- }
217
-
218
179
  #pragma mark - TrueSheetKeyboardObserverDelegate
219
180
 
220
181
  - (void)keyboardWillShow:(CGFloat)height duration:(NSTimeInterval)duration curve:(UIViewAnimationOptions)curve {
@@ -222,8 +183,6 @@ using namespace facebook::react;
222
183
  return;
223
184
  }
224
185
 
225
- _currentKeyboardHeight = height;
226
-
227
186
  TrueSheetViewController *sheetController = _keyboardObserver.viewController;
228
187
  UIView *firstResponder = sheetController ? [sheetController.view findFirstResponder] : nil;
229
188
 
@@ -254,8 +213,6 @@ using namespace facebook::react;
254
213
  return;
255
214
  }
256
215
 
257
- _currentKeyboardHeight = 0;
258
-
259
216
  [UIView animateWithDuration:duration
260
217
  delay:0
261
218
  options:curve | UIViewAnimationOptionBeginFromCurrentState
@@ -275,8 +232,7 @@ using namespace facebook::react;
275
232
 
276
233
  - (void)prepareForRecycle {
277
234
  [super prepareForRecycle];
278
- _currentKeyboardHeight = 0;
279
- [self clearPinning];
235
+ [self clearScrollable];
280
236
  }
281
237
 
282
238
  @end
@@ -254,7 +254,7 @@ using namespace facebook::react;
254
254
  _controller.insetAdjustment = _insetAdjustment;
255
255
 
256
256
  if (_containerView) {
257
- _containerView.scrollViewPinningEnabled = _scrollable;
257
+ _containerView.scrollableEnabled = _scrollable;
258
258
  _containerView.insetAdjustment = _insetAdjustment;
259
259
  _containerView.scrollableOptions = _scrollableOptions;
260
260
  }
@@ -299,7 +299,7 @@ using namespace facebook::react;
299
299
  return;
300
300
 
301
301
  if (_containerView) {
302
- [_containerView setupContentScrollViewPinning];
302
+ [_containerView setupScrollable];
303
303
  }
304
304
 
305
305
  if (_controller.isPresented) {
@@ -366,10 +366,10 @@ using namespace facebook::react;
366
366
  _controller.headerHeight = @(headerHeight);
367
367
  }
368
368
 
369
- _containerView.scrollViewPinningEnabled = _scrollable;
369
+ _containerView.scrollableEnabled = _scrollable;
370
370
  _containerView.insetAdjustment = _insetAdjustment;
371
371
  _containerView.scrollableOptions = _scrollableOptions;
372
- [_containerView setupContentScrollViewPinning];
372
+ [_containerView setupScrollable];
373
373
 
374
374
  if (_eventEmitter) {
375
375
  [TrueSheetLifecycleEvents emitMount:_eventEmitter];
@@ -340,7 +340,7 @@
340
340
 
341
341
  TrueSheetContentView *contentView = [self findContentView:presentedView];
342
342
  if (contentView) {
343
- RCTScrollViewComponentView *scrollViewComponent = [contentView findScrollView:nil];
343
+ RCTScrollViewComponentView *scrollViewComponent = [contentView findScrollView];
344
344
  if (scrollViewComponent && scrollViewComponent.scrollView) {
345
345
  [GestureUtil attachPanGestureHandler:scrollViewComponent.scrollView
346
346
  target:self
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lodev09/react-native-true-sheet",
3
- "version": "3.8.0-beta.0",
3
+ "version": "3.8.0-beta.1",
4
4
  "description": "The true native bottom sheet experience for your React Native Apps.",
5
5
  "source": "./src/index.ts",
6
6
  "main": "./lib/module/index.js",