Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ class NativeViewGestureHandler : GestureHandler() {

hook.afterGestureEnd(event)
} else if (state == STATE_UNDETERMINED || state == STATE_BEGAN) {
if (state != STATE_BEGAN && hook.canBegin(event)) {
begin()
}

when {
shouldActivateOnStart -> {
tryIntercept(view, event)
Expand All @@ -138,12 +142,6 @@ class NativeViewGestureHandler : GestureHandler() {
hook.wantsToHandleEventBeforeActivation() -> {
hook.handleEventBeforeActivation(event)
}

state != STATE_BEGAN -> {
if (hook.canBegin(event)) {
begin()
}
}
}
} else if (state == STATE_ACTIVE) {
hook.sendTouchEvent(view, event)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,12 @@ - (void)bindToView:(UIView *)view
action:@selector(handleTouchUpInside:forEvent:)
forControlEvents:UIControlEventTouchUpInside];
[control addTarget:self action:@selector(handleDragExit:forEvent:) forControlEvents:UIControlEventTouchDragExit];
[control addTarget:self
action:@selector(handleDragInside:forEvent:)
forControlEvents:UIControlEventTouchDragInside];
[control addTarget:self
action:@selector(handleDragOutside:forEvent:)
forControlEvents:UIControlEventTouchDragOutside];
[control addTarget:self action:@selector(handleDragEnter:forEvent:) forControlEvents:UIControlEventTouchDragEnter];
[control addTarget:self action:@selector(handleTouchCancel:forEvent:) forControlEvents:UIControlEventTouchCancel];
} else {
Expand All @@ -161,8 +167,14 @@ - (void)bindToView:(UIView *)view

- (void)unbindFromView
{
UIView *view = self.recognizer.view;

if ([view isKindOfClass:[UIControl class]]) {
[(UIControl *)view removeTarget:self action:NULL forControlEvents:UIControlEventAllEvents];
}

// Restore the React Native's overriden behavor for not delaying content touches
UIScrollView *scrollView = [self retrieveScrollView:self.recognizer.view];
UIScrollView *scrollView = [self retrieveScrollView:view];
scrollView.delaysContentTouches = NO;

[super unbindFromView];
Expand All @@ -184,6 +196,12 @@ - (void)handleTouchDown:(UIView *)sender forEvent:(UIEvent *)event
}
}

[self sendEventsInState:RNGestureHandlerStateBegan
forViewWithTag:sender.reactTag
withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES
withNumberOfTouches:event.allTouches.count
withPointerType:_pointerType]];

[self sendEventsInState:RNGestureHandlerStateActive
forViewWithTag:sender.reactTag
withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES
Expand Down Expand Up @@ -211,22 +229,21 @@ - (void)handleTouchUpInside:(UIView *)sender forEvent:(UIEvent *)event

- (void)handleDragExit:(UIView *)sender forEvent:(UIEvent *)event
{
RNGestureHandlerState newState = RNGestureHandlerStateActive;

// Pointer is moved outside of the view bounds, we cancel button when `shouldCancelWhenOutside` is set
if (self.shouldCancelWhenOutside) {
UIControl *control = (UIControl *)sender;
[control cancelTrackingWithEvent:event];
[self sendEventsInState:RNGestureHandlerStateEnd
forViewWithTag:sender.reactTag
withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO
withNumberOfTouches:event.allTouches.count
withPointerType:_pointerType]];
} else {
[self sendEventsInState:RNGestureHandlerStateActive
forViewWithTag:sender.reactTag
withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO
withNumberOfTouches:event.allTouches.count
withPointerType:_pointerType]];

newState = RNGestureHandlerStateEnd;
}

[self sendEventsInState:newState
forViewWithTag:sender.reactTag
withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO
withNumberOfTouches:event.allTouches.count
withPointerType:_pointerType]];
}

- (void)handleDragEnter:(UIView *)sender forEvent:(UIEvent *)event
Expand All @@ -238,6 +255,24 @@ - (void)handleDragEnter:(UIView *)sender forEvent:(UIEvent *)event
withPointerType:_pointerType]];
}

- (void)handleDragInside:(UIView *)sender forEvent:(UIEvent *)event
{
[self sendEventsInState:RNGestureHandlerStateActive
forViewWithTag:sender.reactTag
withExtraData:[RNGestureHandlerEventExtraData forPointerInside:YES
withNumberOfTouches:event.allTouches.count
withPointerType:_pointerType]];
}

- (void)handleDragOutside:(UIView *)sender forEvent:(UIEvent *)event
{
[self sendEventsInState:RNGestureHandlerStateActive
forViewWithTag:sender.reactTag
withExtraData:[RNGestureHandlerEventExtraData forPointerInside:NO
withNumberOfTouches:event.allTouches.count
withPointerType:_pointerType]];
}

- (void)handleTouchCancel:(UIView *)sender forEvent:(UIEvent *)event
{
[self sendEventsInState:RNGestureHandlerStateCancelled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,7 @@
this.props.onPress(pointerInside);
}

if (
!this.lastActive &&
// NativeViewGestureHandler sends different events based on platform
state === (Platform.OS !== 'android' ? State.ACTIVE : State.BEGAN) &&
pointerInside
) {
if (!this.lastActive && state === State.BEGAN && pointerInside) {
this.longPressDetected = false;
if (this.props.onLongPress) {
this.longPressTimeout = setTimeout(
Expand Down Expand Up @@ -152,14 +147,14 @@
ref,
...props
}: Omit<LegacyBaseButtonProps, 'innerRef'> & {
ref?: React.ForwardedRef<React.ComponentType<any>> | undefined;

Check warning on line 150 in packages/react-native-gesture-handler/src/components/GestureButtons.tsx

View workflow job for this annotation

GitHub Actions / check

Unexpected any. Specify a different type
}) => <InnerBaseButton innerRef={ref} {...props} />;

const AnimatedBaseButton = ({
ref,
...props
}: Animated.AnimatedProps<BaseButtonWithRefProps> & {
ref?: React.ForwardedRef<React.ComponentType<any>> | undefined;

Check warning on line 157 in packages/react-native-gesture-handler/src/components/GestureButtons.tsx

View workflow job for this annotation

GitHub Actions / check

Unexpected any. Specify a different type
}) => <AnimatedInnerBaseButton innerRef={ref} {...props} />;

const btnStyles = StyleSheet.create({
Expand Down Expand Up @@ -187,7 +182,7 @@

private onActiveStateChange = (active: boolean) => {
if (Platform.OS !== 'android') {
this.opacity.setValue(active ? this.props.activeOpacity! : 0);

Check warning on line 185 in packages/react-native-gesture-handler/src/components/GestureButtons.tsx

View workflow job for this annotation

GitHub Actions / check

Forbidden non-null assertion
}

this.props.onActiveStateChange?.(active);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function getIosStatesConfig(
eventName: StateMachineEvent.LONG_PRESS_TOUCHES_DOWN,
},
{
eventName: StateMachineEvent.NATIVE_START,
eventName: StateMachineEvent.NATIVE_BEGIN,
callback: handlePressIn,
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const RawButton = createNativeWrapper<
RawButtonProps
>(GestureHandlerButton, {
shouldCancelWhenOutside: false,
shouldActivateOnStart: false,
shouldActivateOnStart: true,
});

export const BaseButton = (props: BaseButtonProps) => {
Expand All @@ -38,28 +38,21 @@ export const BaseButton = (props: BaseButtonProps) => {
};

const onBegin = (e: CallbackEventType) => {
if (Platform.OS === 'android' && e.pointerInside) {
longPressDetected.current = false;
if (onLongPress) {
longPressTimeout.current = setTimeout(wrappedLongPress, delayLongPress);
}

props.onBegin?.(e);
if (!e.pointerInside) {
return;
}
};

const onActivate = (e: CallbackEventType) => {
onActiveStateChange?.(true);

if (Platform.OS !== 'android' && e.pointerInside) {
longPressDetected.current = false;
if (onLongPress) {
longPressTimeout.current = setTimeout(wrappedLongPress, delayLongPress);
}

props.onBegin?.(e);
longPressDetected.current = false;
if (onLongPress) {
longPressTimeout.current = setTimeout(wrappedLongPress, delayLongPress);
}

props.onBegin?.(e);
};

const onActivate = (e: CallbackEventType) => {
if (!e.pointerInside && longPressTimeout.current !== undefined) {
clearTimeout(longPressTimeout.current);
longPressTimeout.current = undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ const Pressable = (props: PressableProps) => {
stateMachine.handleEvent(StateMachineEvent.NATIVE_BEGIN);
},
onActivate: () => {
if (Platform.OS !== 'android') {
if (Platform.OS !== 'android' && Platform.OS !== 'ios') {
// Native.onActivate is broken with Android + hitSlop
stateMachine.handleEvent(StateMachineEvent.NATIVE_START);
}
Expand All @@ -323,9 +323,7 @@ const Pressable = (props: PressableProps) => {
success ? StateMachineEvent.FINALIZE : StateMachineEvent.CANCEL
);

if (Platform.OS !== 'ios') {
handleFinalize();
}
handleFinalize();
},
enabled: disabled !== true,
disableReanimated: true,
Expand Down
Loading