React Native useAnimatedGestureHandler wird nicht nur in onStart im Web aufgerufen
P粉667649253
2023-08-16 15:21:08
<p><strong>Bevor mir klar wurde, dass onStart() nicht aufgerufen wurde</strong></p>
<p>Die Verwendung von PanGestureHandler im Web und der Versuch, eine AnimatedView zu „ziehen“, funktioniert im Web nicht. Es liegen keine offensichtlichen Fehler vor, die Anwendung wird einwandfrei erstellt und bei der Überprüfung werden in der Konsole keine Warnungen angezeigt. </p>
<p>Es gibt eine Warnung, die mich vermuten lässt, dass dies die Ursache des Problems sein könnte. Ich erhalte eine Warnung auf der Konsole, die lautet: </p>
<p><code>Array-Werte im „Transform“-Stil sind veraltet. Bitte verwenden Sie eine durch Leerzeichen getrennte Zeichenfolgenfunktion, z. B. „scaleX(2) rotationX(15deg)“. </code></p>
<p>Ich verwende eine AnimatedView mit containerStyle, um Objekte beim Ziehen zu transformieren und zu verschieben. </p>
<p><strong>Die Wurzel des Problems</strong></p>
<p>Also habe ich das Problem weiter untersucht und versucht, es zu debuggen, und mir ist aufgefallen, dass der onStart()-Rückruf nicht aufgerufen wurde. Da der onStart()-Callback nicht aufgerufen wird, wird der Kontextwert nie gesetzt und das Kontextobjekt bleibt insgesamt leer. Dies führte zu meinem ursprünglichen Problem, nämlich dass ich keine Objekte ziehen konnte. </p>
<p>Es funktioniert jedoch weiterhin unter iOS. Aus irgendeinem Grund wird unter iOS der Rückruf onStart() aufgerufen. Dies führt dazu, dass der Kontext gefüllt ist und einwandfrei funktioniert. </p>
<p>Das ist mein Code. Denken Sie daran, dass dies nur eine Komponente ist. Im Stammverzeichnis habe ich eine GestureHandlerRootView-Komponente, die die gesamte Anwendung umschließt.</p>
<pre class="brush:php;toolbar:false;">import { View, Image } from 'react-native';
animiert importieren, {
useAnimatedStyle,
useSharedValue,
useAnimatedGestureHandler,
mitFrühling,
} von 'react-native-reanimated';
import { PanGestureHandler, TapGestureHandler } from 'react-native-gesture-handler';
const AnimatedImage = Animated.createAnimatedComponent(Image);
const AnimatedView = Animated.createAnimatedComponent(View);
Exportieren Sie die Standardfunktion EmojiSticker ({ imageSize, stickerSource }) {
const scaleImage = useSharedValue(imageSize);
const translatorX = useSharedValue(0);
const TranslateY = useSharedValue(0);
const onDoubleTap = useAnimatedGestureHandler({
onActive: () => {
if (scaleImage.value !== imageSize * 2) {
ScaleImage.value = ScaleImage.value * 2;
} anders {
ScaleImage.value = ScaleImage.value / 2;
}
},
});
const onDrag = useAnimatedGestureHandler({
onStart: (Ereignis, Kontext) => {
context.translateX = translatorX.value;
context.translateY = translatorY.value;
},
onActive: (Ereignis, Kontext) => {
translatorX.value = event.translationX + context.translateX;
translatorY.value = event.translationY + context.translateY;
},
});
const imageStyle = useAnimatedStyle(() => {
zurückkehren {
Breite: withSpring(scaleImage.value),
Höhe: withSpring(scaleImage.value),
};
});
const containerStyle = useAnimatedStyle(() => {
zurückkehren {
transformieren: [
{
TranslateX: TranslateX.value,
},
{
TranslateY: TranslateY.value,
},
],
};
});
zurückkehren (
<PanGestureHandler onGestureEvent={onDrag}>
<AnimatedView style={[containerStyle, { top: -350 }]}>
<TapGestureHandler onGestureEvent={onDoubleTap} numberOfTaps={2}>
<AnimatedImage
source={stickerSource}
resizeMode='contain'
style={[imageStyle, { width: imageSize, height: imageSize }]}
/>
</TapGestureHandler>
</AnimatedView>
</PanGestureHandler>
);
}</pre>
<p><strong>顺便说一下,双击手势在 Web 和 iOS 上都完美工作.</strong> 我感到困惑, 因为拖动在 iOS 上完美工作, 但在 Web 上却不行.Aufgrund der Abschaffung des Transformationsstils versuche ich, eine Möglichkeit zu finden, webspezifische Stile zu erstellen, aber es fällt mir schwer, eine Situation zu finden, in der andere auf dieses Problem gestoßen sind. Ich glaube, dass es eine echte Lösung gibt, aber vielleicht übersehe ich sie. Ich bin nur wirklich verwirrt, weil es unter iOS perfekt funktioniert, aber nicht im Web. </p>
<p>Ich habe versucht herauszufinden, ob noch jemand ein ähnliches Problem hatte, habe aber nichts Relevantes gefunden. Ich habe auch versucht, auf der Konsole nach der Warnung zu suchen, die ich gesehen habe. </p>
<p><code>Array-Werte im „Transform“-Stil sind veraltet. Bitte verwenden Sie eine durch Leerzeichen getrennte Zeichenfolgenfunktion, z. B. „scaleX(2) rotationX(15deg)“. </code></p>
<p>Zumindest als ich nach etwas gesucht habe, das mit React-Native zu tun hat, habe ich nichts Ähnliches gefunden. </p>
<p>Ich würde gerne eine ziehbare Lösung im Internet finden. </p>
我通过查阅
react-native-reanimated
的文档来解决了这个问题。显然,useAnimatedGestureHandler
并没有被弃用,因为它在onDoubleTap
中起作用,更不用说onDrag
在iOS上也正常工作。但是在处理平移手势的文档中,我找到了这个:
所以,不需要从'react-native-gesture-handler'中导入
PanGestureHandler
和TapGestureHandler
,也不需要从'react-native-reanimated'中导入useAnimatedGestureHandler
,只需要从'react-native-gesture-handler'中导入Gesture
和GestureDetector
。Gesture
取代了useAnimatedGestureHandler
,而GestureDetector
取代了PanGestureHandler
和TapGestureHandler
等组件。我还需要使用
useSharedValue()
创建自己的contextX
和contextY
变量,因为据我所知,onBegin()
和onChange()
回调函数没有可设置的上下文。无论如何,这是修复后的代码,现在在Web和iOS上都完美运行: