@lodev09/react-native-true-sheet 3.0.0-beta.6 → 3.0.0-beta.8
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.
- package/README.md +1 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerView.kt +51 -99
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContainerViewManager.kt +0 -7
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetContentView.kt +10 -18
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetFooterView.kt +76 -20
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetHeaderView.kt +38 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetHeaderViewManager.kt +21 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetPackage.kt +1 -0
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetView.kt +106 -136
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewController.kt +305 -419
- package/android/src/main/java/com/lodev09/truesheet/TrueSheetViewManager.kt +9 -4
- package/android/src/main/java/com/lodev09/truesheet/core/RNScreensFragmentObserver.kt +116 -0
- package/android/src/main/java/com/lodev09/truesheet/utils/ScreenUtils.kt +33 -5
- package/android/src/main/jni/TrueSheetSpec.h +1 -1
- package/common/cpp/react/renderer/components/TrueSheetSpec/{TrueSheetContainerViewComponentDescriptor.h → TrueSheetViewComponentDescriptor.h} +5 -5
- package/common/cpp/react/renderer/components/TrueSheetSpec/{TrueSheetContainerViewShadowNode.cpp → TrueSheetViewShadowNode.cpp} +4 -4
- package/common/cpp/react/renderer/components/TrueSheetSpec/{TrueSheetContainerViewShadowNode.h → TrueSheetViewShadowNode.h} +8 -8
- package/common/cpp/react/renderer/components/TrueSheetSpec/{TrueSheetContainerViewState.cpp → TrueSheetViewState.cpp} +2 -2
- package/common/cpp/react/renderer/components/TrueSheetSpec/{TrueSheetContainerViewState.h → TrueSheetViewState.h} +6 -6
- package/ios/TrueSheetContainerView.h +20 -2
- package/ios/TrueSheetContainerView.mm +62 -62
- package/ios/TrueSheetContentView.h +4 -2
- package/ios/TrueSheetContentView.mm +29 -72
- package/ios/TrueSheetFooterView.mm +2 -2
- package/ios/TrueSheetHeaderView.h +29 -0
- package/ios/TrueSheetHeaderView.mm +60 -0
- package/ios/TrueSheetView.mm +195 -214
- package/ios/TrueSheetViewController.h +2 -2
- package/ios/TrueSheetViewController.mm +126 -231
- package/ios/utils/LayoutUtil.h +2 -1
- package/ios/utils/LayoutUtil.mm +14 -1
- package/lib/module/TrueSheet.js +9 -2
- package/lib/module/TrueSheet.js.map +1 -1
- package/lib/module/fabric/TrueSheetContainerViewNativeComponent.ts +1 -3
- package/lib/module/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
- package/lib/module/fabric/TrueSheetViewNativeComponent.ts +3 -1
- package/lib/typescript/src/TrueSheet.d.ts.map +1 -1
- package/lib/typescript/src/TrueSheet.types.d.ts +9 -9
- package/lib/typescript/src/TrueSheet.types.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetContainerViewNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts +6 -0
- package/lib/typescript/src/fabric/TrueSheetHeaderViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/fabric/TrueSheetViewNativeComponent.d.ts.map +1 -1
- package/package.json +6 -3
- package/react-native.config.js +1 -1
- package/src/TrueSheet.tsx +9 -0
- package/src/TrueSheet.types.ts +10 -11
- package/src/fabric/TrueSheetContainerViewNativeComponent.ts +1 -3
- package/src/fabric/TrueSheetHeaderViewNativeComponent.ts +8 -0
- package/src/fabric/TrueSheetViewNativeComponent.ts +3 -1
package/ios/TrueSheetView.mm
CHANGED
|
@@ -27,16 +27,19 @@
|
|
|
27
27
|
#import "utils/LayoutUtil.h"
|
|
28
28
|
#import "utils/WindowUtil.h"
|
|
29
29
|
|
|
30
|
-
#import <react/renderer/components/TrueSheetSpec/ComponentDescriptors.h>
|
|
31
30
|
#import <react/renderer/components/TrueSheetSpec/EventEmitters.h>
|
|
32
31
|
#import <react/renderer/components/TrueSheetSpec/Props.h>
|
|
33
32
|
#import <react/renderer/components/TrueSheetSpec/RCTComponentViewHelpers.h>
|
|
33
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetViewComponentDescriptor.h>
|
|
34
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetViewShadowNode.h>
|
|
35
|
+
#import <react/renderer/components/TrueSheetSpec/TrueSheetViewState.h>
|
|
34
36
|
|
|
35
37
|
#import <React/RCTConversions.h>
|
|
36
38
|
#import <React/RCTFabricComponentsPlugins.h>
|
|
37
39
|
#import <React/RCTLog.h>
|
|
38
40
|
#import <React/RCTSurfaceTouchHandler.h>
|
|
39
41
|
#import <React/RCTUtils.h>
|
|
42
|
+
#import <react/renderer/core/State.h>
|
|
40
43
|
|
|
41
44
|
using namespace facebook::react;
|
|
42
45
|
|
|
@@ -47,28 +50,31 @@ using namespace facebook::react;
|
|
|
47
50
|
TrueSheetContainerView *_containerView;
|
|
48
51
|
TrueSheetViewController *_controller;
|
|
49
52
|
RCTSurfaceTouchHandler *_touchHandler;
|
|
53
|
+
TrueSheetViewShadowNode::ConcreteState::Shared _state;
|
|
54
|
+
CGSize _lastStateSize;
|
|
50
55
|
NSInteger _initialDetentIndex;
|
|
51
56
|
BOOL _fitScrollView;
|
|
52
57
|
BOOL _initialDetentAnimated;
|
|
58
|
+
BOOL _isSheetUpdatePending;
|
|
53
59
|
}
|
|
54
60
|
|
|
61
|
+
#pragma mark - Initialization
|
|
62
|
+
|
|
55
63
|
- (instancetype)initWithFrame:(CGRect)frame {
|
|
56
64
|
if (self = [super initWithFrame:frame]) {
|
|
57
65
|
static const auto defaultProps = std::make_shared<const TrueSheetViewProps>();
|
|
58
66
|
_props = defaultProps;
|
|
59
67
|
|
|
60
|
-
// Initialize controller - persists across container lifecycle
|
|
61
68
|
_controller = [[TrueSheetViewController alloc] init];
|
|
62
69
|
_controller.delegate = self;
|
|
63
70
|
|
|
64
|
-
// Initialize touch handler - will be attached to container when mounted
|
|
65
71
|
_touchHandler = [[RCTSurfaceTouchHandler alloc] init];
|
|
66
|
-
|
|
67
72
|
_containerView = nil;
|
|
68
|
-
|
|
73
|
+
_lastStateSize = CGSizeZero;
|
|
69
74
|
_initialDetentIndex = -1;
|
|
70
75
|
_initialDetentAnimated = YES;
|
|
71
76
|
_fitScrollView = NO;
|
|
77
|
+
_isSheetUpdatePending = NO;
|
|
72
78
|
}
|
|
73
79
|
return self;
|
|
74
80
|
}
|
|
@@ -76,28 +82,23 @@ using namespace facebook::react;
|
|
|
76
82
|
- (void)didMoveToWindow {
|
|
77
83
|
[super didMoveToWindow];
|
|
78
84
|
|
|
79
|
-
if (!self.window)
|
|
85
|
+
if (!self.window)
|
|
80
86
|
return;
|
|
81
|
-
}
|
|
82
87
|
|
|
83
|
-
// Register
|
|
84
|
-
// This ensures the tag is properly set by the framework
|
|
88
|
+
// Register with TurboModule when tag is set
|
|
85
89
|
if (self.tag > 0) {
|
|
86
90
|
[TrueSheetModule registerView:self withTag:@(self.tag)];
|
|
87
91
|
}
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
- (void)dealloc {
|
|
91
|
-
// Dismiss controller if presented
|
|
92
95
|
if (_controller && _controller.presentingViewController) {
|
|
93
96
|
[_controller dismissViewControllerAnimated:NO completion:nil];
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
// Clean up controller
|
|
97
99
|
_controller.delegate = nil;
|
|
98
100
|
_controller = nil;
|
|
99
101
|
|
|
100
|
-
// Unregister this view from the TurboModule
|
|
101
102
|
[TrueSheetModule unregisterViewWithTag:@(self.tag)];
|
|
102
103
|
}
|
|
103
104
|
|
|
@@ -107,276 +108,262 @@ using namespace facebook::react;
|
|
|
107
108
|
return concreteComponentDescriptorProvider<TrueSheetViewComponentDescriptor>();
|
|
108
109
|
}
|
|
109
110
|
|
|
110
|
-
#pragma mark - TurboModule Methods
|
|
111
|
-
|
|
112
|
-
- (void)presentAtIndex:(NSInteger)index
|
|
113
|
-
animated:(BOOL)animated
|
|
114
|
-
completion:(nullable TrueSheetCompletionBlock)completion {
|
|
115
|
-
if (_controller.isPresented) {
|
|
116
|
-
[_controller.sheetPresentationController animateChanges:^{
|
|
117
|
-
[self->_controller setupActiveDetentWithIndex:index];
|
|
118
|
-
}];
|
|
119
|
-
|
|
120
|
-
if (completion) {
|
|
121
|
-
completion(YES, nil);
|
|
122
|
-
}
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
UIViewController *presentingViewController = [self findPresentingViewController];
|
|
127
|
-
|
|
128
|
-
if (!presentingViewController) {
|
|
129
|
-
NSError *error = [NSError errorWithDomain:@"com.lodev09.TrueSheet"
|
|
130
|
-
code:1001
|
|
131
|
-
userInfo:@{NSLocalizedDescriptionKey : @"No presenting view controller found"}];
|
|
132
|
-
|
|
133
|
-
if (completion) {
|
|
134
|
-
completion(NO, error);
|
|
135
|
-
}
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// Setup our sheet properties
|
|
140
|
-
[_controller setupSheetProps];
|
|
141
|
-
[_controller setupSheetDetents];
|
|
142
|
-
|
|
143
|
-
// Set to the given detent index
|
|
144
|
-
[_controller setupActiveDetentWithIndex:index];
|
|
145
|
-
|
|
146
|
-
// Present our sheet
|
|
147
|
-
[presentingViewController presentViewController:self->_controller
|
|
148
|
-
animated:animated
|
|
149
|
-
completion:^{
|
|
150
|
-
// Call completion handler
|
|
151
|
-
if (completion) {
|
|
152
|
-
completion(YES, nil);
|
|
153
|
-
}
|
|
154
|
-
}];
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
- (void)dismissAnimated:(BOOL)animated completion:(nullable TrueSheetCompletionBlock)completion {
|
|
158
|
-
if (!_controller.isPresented) {
|
|
159
|
-
if (completion) {
|
|
160
|
-
completion(YES, nil);
|
|
161
|
-
}
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
[_controller dismissViewControllerAnimated:animated
|
|
166
|
-
completion:^{
|
|
167
|
-
if (completion) {
|
|
168
|
-
completion(YES, nil);
|
|
169
|
-
}
|
|
170
|
-
}];
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
- (void)resizeToIndex:(NSInteger)index {
|
|
174
|
-
if (_controller.isPresented) {
|
|
175
|
-
[_controller.sheetPresentationController animateChanges:^{
|
|
176
|
-
[self->_controller setupActiveDetentWithIndex:index];
|
|
177
|
-
}];
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
111
|
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps {
|
|
182
112
|
[super updateProps:props oldProps:oldProps];
|
|
183
113
|
|
|
184
114
|
const auto &newProps = *std::static_pointer_cast<TrueSheetViewProps const>(props);
|
|
185
115
|
|
|
186
|
-
//
|
|
116
|
+
// Detents (-1 represents "auto")
|
|
187
117
|
NSMutableArray *detents = [NSMutableArray new];
|
|
188
118
|
for (const auto &detent : newProps.detents) {
|
|
189
119
|
[detents addObject:@(detent)];
|
|
190
120
|
}
|
|
191
|
-
|
|
192
121
|
_controller.detents = detents;
|
|
193
122
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
UIColor *color = RCTUIColorFromSharedColor(SharedColor(newProps.background));
|
|
198
|
-
_controller.backgroundColor = color;
|
|
199
|
-
}
|
|
123
|
+
// Background color
|
|
124
|
+
_controller.backgroundColor =
|
|
125
|
+
newProps.background == 0 ? nil : RCTUIColorFromSharedColor(SharedColor(newProps.background));
|
|
200
126
|
|
|
201
|
-
//
|
|
127
|
+
// Blur tint
|
|
202
128
|
_controller.blurTint = !newProps.blurTint.empty() ? RCTNSStringFromString(newProps.blurTint) : nil;
|
|
203
129
|
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
_controller.cornerRadius = nil;
|
|
207
|
-
} else {
|
|
208
|
-
_controller.cornerRadius = @(newProps.cornerRadius);
|
|
209
|
-
}
|
|
130
|
+
// Corner radius
|
|
131
|
+
_controller.cornerRadius = newProps.cornerRadius < 0 ? nil : @(newProps.cornerRadius);
|
|
210
132
|
|
|
211
|
-
//
|
|
133
|
+
// Max height
|
|
212
134
|
if (newProps.maxHeight != 0.0) {
|
|
213
135
|
_controller.maxHeight = @(newProps.maxHeight);
|
|
214
136
|
}
|
|
215
137
|
|
|
216
|
-
// Update grabber
|
|
217
138
|
_controller.grabber = newProps.grabber;
|
|
218
|
-
|
|
219
|
-
// Update page sizing
|
|
220
139
|
_controller.pageSizing = newProps.pageSizing;
|
|
221
|
-
|
|
222
|
-
// Update dismissible
|
|
223
140
|
_controller.modalInPresentation = !newProps.dismissible;
|
|
224
|
-
|
|
225
|
-
// Update dimmed
|
|
226
141
|
_controller.dimmed = newProps.dimmed;
|
|
227
142
|
|
|
228
|
-
// Update dimmedDetentIndex
|
|
229
143
|
if (newProps.dimmedDetentIndex >= 0) {
|
|
230
144
|
_controller.dimmedDetentIndex = @(newProps.dimmedDetentIndex);
|
|
231
145
|
}
|
|
232
146
|
|
|
233
|
-
// Store initial presentation settings
|
|
234
147
|
_initialDetentIndex = newProps.initialDetentIndex;
|
|
235
148
|
_initialDetentAnimated = newProps.initialDetentAnimated;
|
|
236
|
-
|
|
237
|
-
// Store ScrollView fit prop
|
|
238
149
|
_fitScrollView = newProps.fitScrollView;
|
|
150
|
+
|
|
151
|
+
if (_containerView) {
|
|
152
|
+
_containerView.scrollViewPinningEnabled = _fitScrollView;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
- (void)updateState:(const State::Shared &)state oldState:(const State::Shared &)oldState {
|
|
157
|
+
_state = std::static_pointer_cast<TrueSheetViewShadowNode::ConcreteState const>(state);
|
|
158
|
+
|
|
159
|
+
if (_controller) {
|
|
160
|
+
[self updateStateWithSize:_controller.view.frame.size];
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Updates Fabric state with container width for Yoga layout.
|
|
166
|
+
*/
|
|
167
|
+
- (void)updateStateWithSize:(CGSize)size {
|
|
168
|
+
if (!_state || size.width <= 0 || size.width == _lastStateSize.width)
|
|
169
|
+
return;
|
|
170
|
+
|
|
171
|
+
_lastStateSize = size;
|
|
172
|
+
_state->updateState([=](TrueSheetViewShadowNode::ConcreteState::Data const &oldData)
|
|
173
|
+
-> TrueSheetViewShadowNode::ConcreteState::SharedData {
|
|
174
|
+
auto newData = oldData;
|
|
175
|
+
newData.containerWidth = static_cast<float>(size.width);
|
|
176
|
+
return std::make_shared<TrueSheetViewShadowNode::ConcreteState::Data const>(newData);
|
|
177
|
+
});
|
|
239
178
|
}
|
|
240
179
|
|
|
241
180
|
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask {
|
|
242
181
|
[super finalizeUpdates:updateMask];
|
|
243
182
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (!_controller)
|
|
247
|
-
return;
|
|
183
|
+
if (!(updateMask & RNComponentViewUpdateMaskProps) || !_controller)
|
|
184
|
+
return;
|
|
248
185
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
186
|
+
if (_containerView) {
|
|
187
|
+
[_containerView setupContentScrollViewPinning];
|
|
188
|
+
}
|
|
253
189
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
[_controller
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
// Handle initial presentation
|
|
263
|
-
if (_initialDetentIndex >= 0 && !_controller.isPresented) {
|
|
264
|
-
[self presentAtIndex:_initialDetentIndex animated:_initialDetentAnimated completion:nil];
|
|
265
|
-
}
|
|
266
|
-
}
|
|
190
|
+
if (_controller.isPresented) {
|
|
191
|
+
[_controller.sheetPresentationController animateChanges:^{
|
|
192
|
+
[self->_controller setupSheetProps];
|
|
193
|
+
[self->_controller setupSheetDetents];
|
|
194
|
+
[self->_controller applyActiveDetent];
|
|
195
|
+
}];
|
|
196
|
+
} else if (_initialDetentIndex >= 0) {
|
|
197
|
+
[self presentAtIndex:_initialDetentIndex animated:_initialDetentAnimated completion:nil];
|
|
267
198
|
}
|
|
268
199
|
}
|
|
269
200
|
|
|
270
|
-
- (void)
|
|
271
|
-
|
|
272
|
-
if ([childComponentView isKindOfClass:[TrueSheetContainerView class]]) {
|
|
273
|
-
if (_containerView != nil) {
|
|
274
|
-
RCTLogWarn(@"TrueSheet: Sheet can only have one container component.");
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
201
|
+
- (void)prepareForRecycle {
|
|
202
|
+
[super prepareForRecycle];
|
|
277
203
|
|
|
278
|
-
|
|
204
|
+
_lastStateSize = CGSizeZero;
|
|
279
205
|
|
|
280
|
-
|
|
281
|
-
|
|
206
|
+
if (_controller && _controller.presentingViewController) {
|
|
207
|
+
[_controller dismissViewControllerAnimated:YES completion:nil];
|
|
208
|
+
}
|
|
282
209
|
|
|
283
|
-
|
|
284
|
-
|
|
210
|
+
[TrueSheetModule unregisterViewWithTag:@(self.tag)];
|
|
211
|
+
}
|
|
285
212
|
|
|
286
|
-
|
|
287
|
-
[_controller.view addSubview:_containerView];
|
|
213
|
+
#pragma mark - Child Component Mounting
|
|
288
214
|
|
|
289
|
-
|
|
290
|
-
|
|
215
|
+
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
216
|
+
if (![childComponentView isKindOfClass:[TrueSheetContainerView class]])
|
|
217
|
+
return;
|
|
291
218
|
|
|
292
|
-
|
|
293
|
-
|
|
219
|
+
if (_containerView != nil) {
|
|
220
|
+
RCTLogWarn(@"TrueSheet: Sheet can only have one container component.");
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
294
223
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
[_controller.view layoutIfNeeded];
|
|
224
|
+
_containerView = (TrueSheetContainerView *)childComponentView;
|
|
225
|
+
_containerView.delegate = self;
|
|
298
226
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
}
|
|
227
|
+
[_touchHandler attachToView:_containerView];
|
|
228
|
+
[_controller.view addSubview:_containerView];
|
|
229
|
+
[LayoutUtil pinView:_containerView toParentView:_controller.view edges:UIRectEdgeAll];
|
|
230
|
+
[_controller.view bringSubviewToFront:_containerView];
|
|
304
231
|
|
|
305
|
-
|
|
306
|
-
|
|
232
|
+
CGFloat contentHeight = [_containerView contentHeight];
|
|
233
|
+
if (contentHeight > 0) {
|
|
234
|
+
_controller.contentHeight = @(contentHeight);
|
|
235
|
+
}
|
|
307
236
|
|
|
308
|
-
|
|
309
|
-
|
|
237
|
+
CGFloat headerHeight = [_containerView headerHeight];
|
|
238
|
+
if (headerHeight > 0) {
|
|
239
|
+
_controller.headerHeight = @(headerHeight);
|
|
310
240
|
}
|
|
241
|
+
|
|
242
|
+
_containerView.scrollViewPinningEnabled = _fitScrollView;
|
|
243
|
+
[_containerView setupContentScrollViewPinning];
|
|
244
|
+
|
|
245
|
+
[OnMountEvent emit:_eventEmitter];
|
|
311
246
|
}
|
|
312
247
|
|
|
313
248
|
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index {
|
|
314
|
-
if ([childComponentView isKindOfClass:[TrueSheetContainerView class]])
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
// Detach touch handler
|
|
318
|
-
if (_touchHandler) {
|
|
319
|
-
[_touchHandler detachFromView:_containerView];
|
|
320
|
-
}
|
|
249
|
+
if (![childComponentView isKindOfClass:[TrueSheetContainerView class]])
|
|
250
|
+
return;
|
|
321
251
|
|
|
322
|
-
|
|
323
|
-
[LayoutUtil unpinView:_containerView];
|
|
324
|
-
[_containerView removeFromSuperview];
|
|
252
|
+
_containerView.delegate = nil;
|
|
325
253
|
|
|
326
|
-
|
|
254
|
+
if (_touchHandler) {
|
|
255
|
+
[_touchHandler detachFromView:_containerView];
|
|
327
256
|
}
|
|
257
|
+
|
|
258
|
+
[LayoutUtil unpinView:_containerView fromParentView:nil];
|
|
259
|
+
[_containerView removeFromSuperview];
|
|
260
|
+
_containerView = nil;
|
|
328
261
|
}
|
|
329
262
|
|
|
330
|
-
-
|
|
331
|
-
[super prepareForRecycle];
|
|
263
|
+
#pragma mark - TurboModule Methods
|
|
332
264
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
265
|
+
- (void)presentAtIndex:(NSInteger)index
|
|
266
|
+
animated:(BOOL)animated
|
|
267
|
+
completion:(nullable TrueSheetCompletionBlock)completion {
|
|
268
|
+
if (_controller.isPresented) {
|
|
269
|
+
[_controller.sheetPresentationController animateChanges:^{
|
|
270
|
+
[self->_controller setupActiveDetentWithIndex:index];
|
|
271
|
+
}];
|
|
272
|
+
if (completion) {
|
|
273
|
+
completion(YES, nil);
|
|
274
|
+
}
|
|
275
|
+
return;
|
|
336
276
|
}
|
|
337
277
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
278
|
+
UIViewController *presentingViewController = [self findPresentingViewController];
|
|
279
|
+
if (!presentingViewController) {
|
|
280
|
+
NSError *error = [NSError errorWithDomain:@"com.lodev09.TrueSheet"
|
|
281
|
+
code:1001
|
|
282
|
+
userInfo:@{NSLocalizedDescriptionKey : @"No presenting view controller found"}];
|
|
283
|
+
if (completion) {
|
|
284
|
+
completion(NO, error);
|
|
285
|
+
}
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
[_controller setupSheetProps];
|
|
290
|
+
[_controller setupSheetDetents];
|
|
291
|
+
[_controller setupActiveDetentWithIndex:index];
|
|
292
|
+
|
|
293
|
+
[presentingViewController presentViewController:_controller
|
|
294
|
+
animated:animated
|
|
295
|
+
completion:^{
|
|
296
|
+
if (completion) {
|
|
297
|
+
completion(YES, nil);
|
|
298
|
+
}
|
|
299
|
+
}];
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
- (void)dismissAnimated:(BOOL)animated completion:(nullable TrueSheetCompletionBlock)completion {
|
|
303
|
+
if (!_controller.isPresented) {
|
|
304
|
+
if (completion) {
|
|
305
|
+
completion(YES, nil);
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
[_controller dismissViewControllerAnimated:animated
|
|
311
|
+
completion:^{
|
|
312
|
+
if (completion) {
|
|
313
|
+
completion(YES, nil);
|
|
314
|
+
}
|
|
315
|
+
}];
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
- (void)resizeToIndex:(NSInteger)index {
|
|
319
|
+
if (_controller.isPresented) {
|
|
320
|
+
[_controller.sheetPresentationController animateChanges:^{
|
|
321
|
+
[self->_controller setupActiveDetentWithIndex:index];
|
|
322
|
+
}];
|
|
323
|
+
}
|
|
341
324
|
}
|
|
342
325
|
|
|
343
326
|
#pragma mark - TrueSheetContainerViewDelegate
|
|
344
327
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
328
|
+
/**
|
|
329
|
+
* Debounced sheet update to handle rapid content/header size changes.
|
|
330
|
+
*/
|
|
331
|
+
- (void)updateSheetIfNeeded {
|
|
332
|
+
if (!_controller.isPresented || _isSheetUpdatePending)
|
|
333
|
+
return;
|
|
349
334
|
|
|
350
|
-
|
|
335
|
+
_isSheetUpdatePending = YES;
|
|
351
336
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
// Controller viewDidLayoutSubviews will handle position notification.
|
|
356
|
-
_controller.layoutTransitioning = YES;
|
|
337
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
338
|
+
self->_isSheetUpdatePending = NO;
|
|
339
|
+
self->_controller.layoutTransitioning = YES;
|
|
357
340
|
|
|
358
|
-
[_controller.sheetPresentationController animateChanges:^{
|
|
341
|
+
[self->_controller.sheetPresentationController animateChanges:^{
|
|
359
342
|
[self->_controller setupSheetDetents];
|
|
360
343
|
}];
|
|
361
|
-
}
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
- (void)containerViewContentDidChangeSize:(CGSize)newSize {
|
|
348
|
+
_controller.contentHeight = @(newSize.height);
|
|
349
|
+
[self updateSheetIfNeeded];
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
- (void)containerViewHeaderDidChangeSize:(CGSize)newSize {
|
|
353
|
+
_controller.headerHeight = @(newSize.height);
|
|
354
|
+
[self updateSheetIfNeeded];
|
|
362
355
|
}
|
|
363
356
|
|
|
364
357
|
#pragma mark - TrueSheetViewControllerDelegate
|
|
365
358
|
|
|
366
359
|
- (void)viewControllerWillPresent {
|
|
367
360
|
NSInteger index = [_controller currentDetentIndex];
|
|
368
|
-
CGFloat position = _controller.currentPosition;
|
|
369
|
-
|
|
370
361
|
_controller.activeDetentIndex = index;
|
|
371
|
-
|
|
372
|
-
[OnWillPresentEvent emit:_eventEmitter index:index position:position];
|
|
362
|
+
[OnWillPresentEvent emit:_eventEmitter index:index position:_controller.currentPosition];
|
|
373
363
|
}
|
|
374
364
|
|
|
375
365
|
- (void)viewControllerDidPresent {
|
|
376
|
-
|
|
377
|
-
CGFloat position = _controller.currentPosition;
|
|
378
|
-
|
|
379
|
-
[OnDidPresentEvent emit:_eventEmitter index:index position:position];
|
|
366
|
+
[OnDidPresentEvent emit:_eventEmitter index:[_controller currentDetentIndex] position:_controller.currentPosition];
|
|
380
367
|
}
|
|
381
368
|
|
|
382
369
|
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state index:(NSInteger)index position:(CGFloat)position {
|
|
@@ -384,16 +371,13 @@ using namespace facebook::react;
|
|
|
384
371
|
case UIGestureRecognizerStateBegan:
|
|
385
372
|
[OnDragBeginEvent emit:_eventEmitter index:index position:position];
|
|
386
373
|
break;
|
|
387
|
-
|
|
388
374
|
case UIGestureRecognizerStateChanged:
|
|
389
375
|
[OnDragChangeEvent emit:_eventEmitter index:index position:position];
|
|
390
376
|
break;
|
|
391
|
-
|
|
392
377
|
case UIGestureRecognizerStateEnded:
|
|
393
378
|
case UIGestureRecognizerStateCancelled:
|
|
394
379
|
[OnDragEndEvent emit:_eventEmitter index:index position:position];
|
|
395
380
|
break;
|
|
396
|
-
|
|
397
381
|
default:
|
|
398
382
|
break;
|
|
399
383
|
}
|
|
@@ -405,7 +389,6 @@ using namespace facebook::react;
|
|
|
405
389
|
|
|
406
390
|
- (void)viewControllerDidDismiss {
|
|
407
391
|
_controller.activeDetentIndex = -1;
|
|
408
|
-
|
|
409
392
|
[OnDidDismissEvent emit:_eventEmitter];
|
|
410
393
|
}
|
|
411
394
|
|
|
@@ -413,7 +396,6 @@ using namespace facebook::react;
|
|
|
413
396
|
if (_controller.activeDetentIndex != index) {
|
|
414
397
|
_controller.activeDetentIndex = index;
|
|
415
398
|
}
|
|
416
|
-
|
|
417
399
|
[OnDetentChangeEvent emit:_eventEmitter index:index position:position];
|
|
418
400
|
}
|
|
419
401
|
|
|
@@ -421,30 +403,29 @@ using namespace facebook::react;
|
|
|
421
403
|
[OnPositionChangeEvent emit:_eventEmitter index:index position:position transitioning:transitioning];
|
|
422
404
|
}
|
|
423
405
|
|
|
406
|
+
- (void)viewControllerDidChangeSize:(CGSize)size {
|
|
407
|
+
[self updateStateWithSize:size];
|
|
408
|
+
}
|
|
409
|
+
|
|
424
410
|
#pragma mark - Private Helpers
|
|
425
411
|
|
|
426
412
|
- (UIViewController *)findPresentingViewController {
|
|
427
413
|
UIWindow *keyWindow = [WindowUtil keyWindow];
|
|
428
|
-
|
|
429
|
-
if (!keyWindow) {
|
|
414
|
+
if (!keyWindow)
|
|
430
415
|
return nil;
|
|
431
|
-
}
|
|
432
416
|
|
|
433
417
|
UIViewController *rootViewController = keyWindow.rootViewController;
|
|
434
|
-
|
|
435
|
-
if (!rootViewController) {
|
|
418
|
+
if (!rootViewController)
|
|
436
419
|
return nil;
|
|
437
|
-
}
|
|
438
420
|
|
|
439
|
-
// Find
|
|
421
|
+
// Find topmost presented view controller
|
|
440
422
|
while (rootViewController.presentedViewController) {
|
|
441
423
|
UIViewController *presented = rootViewController.presentedViewController;
|
|
442
424
|
|
|
443
|
-
// Skip TrueSheetViewController if
|
|
425
|
+
// Skip TrueSheetViewController if being dismissed
|
|
444
426
|
if ([presented isKindOfClass:[TrueSheetViewController class]] && presented.isBeingDismissed) {
|
|
445
427
|
break;
|
|
446
428
|
}
|
|
447
|
-
|
|
448
429
|
rootViewController = presented;
|
|
449
430
|
}
|
|
450
431
|
|
|
@@ -26,6 +26,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
26
26
|
- (void)viewControllerDidChangeDetent:(NSInteger)index position:(CGFloat)position;
|
|
27
27
|
- (void)viewControllerDidDrag:(UIGestureRecognizerState)state index:(NSInteger)index position:(CGFloat)position;
|
|
28
28
|
- (void)viewControllerDidChangePosition:(NSInteger)index position:(CGFloat)position transitioning:(BOOL)transitioning;
|
|
29
|
+
- (void)viewControllerDidChangeSize:(CGSize)size;
|
|
29
30
|
|
|
30
31
|
@end
|
|
31
32
|
|
|
@@ -40,6 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
40
41
|
@property (nonatomic, strong) NSArray *detents;
|
|
41
42
|
@property (nonatomic, strong, nullable) NSNumber *maxHeight;
|
|
42
43
|
@property (nonatomic, strong, nullable) NSNumber *contentHeight;
|
|
44
|
+
@property (nonatomic, strong, nullable) NSNumber *headerHeight;
|
|
43
45
|
@property (nonatomic, strong, nullable) UIColor *backgroundColor;
|
|
44
46
|
@property (nonatomic, strong, nullable) NSNumber *cornerRadius;
|
|
45
47
|
@property (nonatomic, assign) BOOL grabber;
|
|
@@ -58,8 +60,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
58
60
|
- (NSInteger)currentDetentIndex;
|
|
59
61
|
- (CGFloat)currentPosition;
|
|
60
62
|
- (CGFloat)bottomInset;
|
|
61
|
-
- (CGFloat)currentHeight;
|
|
62
|
-
- (CGFloat)containerHeight;
|
|
63
63
|
|
|
64
64
|
@end
|
|
65
65
|
|