@@ -24,8 +24,16 @@ typedef NS_ENUM(NSInteger, RNGestureHandlerMutation) {
24
24
RNGestureHandlerMutationKeep,
25
25
};
26
26
27
+ struct LogicChild {
28
+ RNGHUIView *view;
29
+ std::vector<int > handlerTags;
30
+ NSMutableSet *nativeHandlers;
31
+ NSMutableSet *attachedHandlers;
32
+ };
33
+
27
34
@implementation RNGestureHandlerDetector {
28
35
int _moduleId;
36
+ std::unordered_map<int , LogicChild> logicChildren;
29
37
}
30
38
31
39
#if TARGET_OS_OSX
@@ -87,6 +95,30 @@ - (void)dispatchTouchEvent:(RNGestureHandlerDetectorEventEmitter::OnGestureHandl
87
95
}
88
96
}
89
97
98
+ - (void )dispatchLogicStateChangeEvent : (RNGestureHandlerDetectorEventEmitter::OnGestureHandlerLogicStateChange)event
99
+ {
100
+ if (_eventEmitter != nullptr ) {
101
+ std::dynamic_pointer_cast<const RNGestureHandlerDetectorEventEmitter>(_eventEmitter)
102
+ ->onGestureHandlerLogicStateChange (event);
103
+ }
104
+ }
105
+
106
+ - (void )dispatchLogicGestureEvent : (RNGestureHandlerDetectorEventEmitter::OnGestureHandlerLogicEvent)event
107
+ {
108
+ if (_eventEmitter != nullptr ) {
109
+ std::dynamic_pointer_cast<const RNGestureHandlerDetectorEventEmitter>(_eventEmitter)
110
+ ->onGestureHandlerLogicEvent (event);
111
+ }
112
+ }
113
+
114
+ - (void )dispatchLogicTouchEvent : (RNGestureHandlerDetectorEventEmitter::OnGestureHandlerLogicTouchEvent)event
115
+ {
116
+ if (_eventEmitter != nullptr ) {
117
+ std::dynamic_pointer_cast<const RNGestureHandlerDetectorEventEmitter>(_eventEmitter)
118
+ ->onGestureHandlerLogicTouchEvent (event);
119
+ }
120
+ }
121
+
90
122
- (BOOL )shouldAttachGestureToSubview : (NSNumber *)handlerTag
91
123
{
92
124
RNGestureHandlerManager *handlerManager = [RNGestureHandlerModule handlerManagerForModuleId: _moduleId];
@@ -125,25 +157,24 @@ - (void)updateLayoutMetrics:(const LayoutMetrics &)layoutMetrics
125
157
[super updateLayoutMetrics: newLayoutMetrics oldLayoutMetrics: oldLayoutMetrics];
126
158
}
127
159
128
- - (void )updateProps : (const Props::Shared &)propsBase oldProps : (const Props::Shared &)oldPropsBase
129
- {
130
- const auto &newProps = *std::static_pointer_cast<const RNGestureHandlerDetectorProps>(propsBase);
131
- const auto &oldProps = *std::static_pointer_cast<const RNGestureHandlerDetectorProps>(oldPropsBase);
160
+ - (void )updatePropsInternal : (const std::vector<int> &)handlerTags
161
+ oldHandlerTags : (const std::vector<int> &)oldHandlerTags
162
+ isLogic : (bool )isLogic
163
+ viewTag : (const int )viewTag
164
+ attachedHandlers : (NSMutableSet *)attachedHandlers
165
+ nativeHandlers : (NSMutableSet *)nativeHandlers
132
166
133
- _moduleId = newProps. moduleId ;
167
+ {
134
168
RNGestureHandlerManager *handlerManager = [RNGestureHandlerModule handlerManagerForModuleId: _moduleId];
135
169
react_native_assert (handlerManager != nullptr && " Tried to access a non-existent handler manager" )
136
170
137
171
std::unordered_map<int , RNGestureHandlerMutation>
138
172
changes;
139
-
140
- if (oldPropsBase != nullptr ) {
141
- for (const auto oldHandler : oldProps.handlerTags ) {
142
- changes[oldHandler] = RNGestureHandlerMutationDetach;
143
- }
173
+ for (const auto oldHandler : oldHandlerTags) {
174
+ changes[oldHandler] = RNGestureHandlerMutationDetach;
144
175
}
145
176
146
- for (const auto newHandler : newProps. handlerTags ) {
177
+ for (const auto newHandler : handlerTags) {
147
178
changes[newHandler] = changes.contains (newHandler) ? RNGestureHandlerMutationKeep : RNGestureHandlerMutationAttach;
148
179
}
149
180
@@ -154,27 +185,69 @@ - (void)updateProps:(const Props::Shared &)propsBase oldProps:(const Props::Shar
154
185
if ([self shouldAttachGestureToSubview: handlerTag]) {
155
186
// It might happen that `attachHandlers` will be called before children are added into view hierarchy. In that
156
187
// case we cannot attach `NativeViewGestureHandlers` here and we have to do it in `didAddSubview` method.
157
- [_nativeHandlers addObject: handlerTag];
188
+ [nativeHandlers addObject: handlerTag];
158
189
} else {
159
- [handlerManager.registry attachHandlerWithTag: handlerTag
160
- toView: self
161
- withActionType: RNGestureHandlerActionTypeNativeDetector];
162
-
163
- [_attachedHandlers addObject: handlerTag];
190
+ if (isLogic) {
191
+ [handlerManager attachGestureHandler: handlerTag
192
+ toViewWithTag: @(viewTag)
193
+ withActionType: RNGestureHandlerActionTypeLogicDetector];
194
+ } else {
195
+ [handlerManager.registry attachHandlerWithTag: handlerTag
196
+ toView: self
197
+ withActionType: RNGestureHandlerActionTypeNativeDetector];
198
+ }
199
+ [attachedHandlers addObject: handlerTag];
164
200
}
165
201
} else if (handlerChange.second == RNGestureHandlerMutationDetach) {
166
202
[handlerManager.registry detachHandlerWithTag: handlerTag];
167
- [_attachedHandlers removeObject: handlerTag];
168
- [_nativeHandlers removeObject: handlerTag];
203
+ [attachedHandlers removeObject: handlerTag];
204
+ [nativeHandlers removeObject: handlerTag];
169
205
}
170
206
}
171
207
172
208
// This covers the case where `NativeViewGestureHandlers` are attached after child views were created.
173
209
if (!self.subviews [0 ]) {
174
210
[self tryAttachNativeHandlersToChildView ];
175
211
}
212
+ }
213
+
214
+ - (void )updateProps : (const Props::Shared &)propsBase oldProps : (const Props::Shared &)oldPropsBase
215
+ {
216
+ const auto &newProps = *std::static_pointer_cast<const RNGestureHandlerDetectorProps>(propsBase);
217
+ const auto &oldProps = *std::static_pointer_cast<const RNGestureHandlerDetectorProps>(oldPropsBase);
218
+ _moduleId = newProps.moduleId ;
176
219
220
+ static std::vector<int > emptyVector;
221
+ const std::vector<int > &oldHandlerTags = (oldPropsBase != nullptr ) ? oldProps.handlerTags : emptyVector;
222
+
223
+ [self updatePropsInternal: newProps.handlerTags
224
+ oldHandlerTags: oldHandlerTags
225
+ isLogic: false
226
+ viewTag: -1
227
+ attachedHandlers: _attachedHandlers
228
+ nativeHandlers: _nativeHandlers];
177
229
[super updateProps: propsBase oldProps: oldPropsBase];
230
+
231
+ for (const RNGestureHandlerDetectorLogicChildrenStruct &child : newProps.logicChildren ) {
232
+ if (logicChildren.find (child.viewTag ) == logicChildren.end ()) {
233
+ // Initialize the vector for a new logic child
234
+ RNGestureHandlerManager *handlerManager = [RNGestureHandlerModule handlerManagerForModuleId: _moduleId];
235
+ react_native_assert (handlerManager != nullptr && " Tried to access a non-existent handler manager" )
236
+ logicChildren[child.viewTag]
237
+ .view = [handlerManager viewForReactTag: @(child.viewTag)];
238
+ logicChildren[child.viewTag].handlerTags = {};
239
+ logicChildren[child.viewTag].attachedHandlers = [NSMutableSet set ];
240
+ logicChildren[child.viewTag].nativeHandlers = [NSMutableSet set ];
241
+ [[handlerManager registry ] registerLogicChild: @(child.viewTag) toParent: @(self .tag)];
242
+ }
243
+ [self updatePropsInternal: child.handlerTags
244
+ oldHandlerTags: logicChildren[child.viewTag].handlerTags
245
+ isLogic: true
246
+ viewTag: child.viewTag
247
+ attachedHandlers: logicChildren[child.viewTag].attachedHandlers
248
+ nativeHandlers: logicChildren[child.viewTag].nativeHandlers];
249
+ }
250
+
178
251
// Override to force hittesting to work outside bounds
179
252
self.clipsToBounds = NO ;
180
253
}
0 commit comments