React Native useAnimatedGestureHandler が Web 上の onStart でのみ呼び出されない
P粉667649253
2023-08-16 15:21:08
<p><strong>気づく前に onStart() が呼び出されていません</strong></p>
<p>Web 上で PanGestureHandler を使用し、AnimatedView を「ドラッグ」しようとしても、Web 上では機能しません。明らかなエラーはなく、アプリケーションは正常にビルドされ、チェック時にコンソールに警告は表示されません。 </p>
<p>これが問題の原因である可能性があると思われる警告があります。コンソールに次のような警告が表示されます: </p>
<p><code>「transform」スタイルの配列値は非推奨になりました。 「scaleX(2)rotateX(15deg)」などのスペース区切りの文字列関数を使用してください。 </code></p>
<p>コンテナスタイルで AnimatedView を使用して、ドラッグ時にオブジェクトを変形および移動します。 </p>
<p><strong>問題の根本</strong></p>
<p>そこで、デバッグしようとして問題をさらに調査したところ、onStart() コールバックが呼び出されないことに気付きました。 onStart() コールバックは呼び出されないため、コンテキスト値は設定されず、コンテキスト オブジェクトは全体的に空のままになります。これにより、オブジェクトをドラッグできないという最初の問題が発生しました。 </p>
<p>ただし、iOS でも引き続き動作します。何らかの理由で、iOS では onStart() コールバックが呼び出されます。これにより、コンテキストが設定され、正常に動作します。 </p>
<p>これは私のコードです。これは単なるコンポーネントであることに注意してください。ルート ディレクトリには、アプリケーション全体をラップする GestureHandlerRootView コンポーネントがあります。</p>
<pre class="brush:php;toolbar:false;">import { View, Image } from 'react-native';
インポートアニメーション、{
AnimatedStyle を使用する、
useSharedValue、
AnimatedGestureHandler を使用する、
春とともに、
'react-native-reanimated' から;
import { PanGestureHandler, TapGestureHandler } from 'react-native-gesture-handler';
const AnimatedImage = Animated.createAnimatedComponent(画像);
const AnimatedView = Animated.createAnimatedComponent(View);
デフォルト関数 EmojiSticker ({ imageSize, StickerSource }) {をエクスポートします。
constscaleImage = useSharedValue(imageSize);
const translationX = useSharedValue(0);
const translationY = useSharedValue(0);
const onDoubleTap = useAnimatedGestureHandler({
onActive: () => {
if (scaleImage.value !== imageSize * 2) {
スケールイメージ.値 = スケールイメージ.値 * 2;
} それ以外 {
スケールイメージ.値 = スケールイメージ.値 / 2;
}
}、
});
const onDrag = useAnimatedGestureHandler({
onStart: (イベント、コンテキスト) => {
context.translateX = translationX.value;
context.translateY = translationY.value;
}、
onActive: (イベント、コンテキスト) => {
翻訳X.値 = イベント.翻訳X コンテキスト.翻訳X;
翻訳 Y.値 = イベント.翻訳 Y コンテキスト.翻訳 Y;
}、
});
const imageStyle = useAnimatedStyle(() => {
戻る {
幅: withSpring(scaleImage.value),
高さ: withSpring(scaleImage.value),
};
});
constcontainerStyle = useAnimatedStyle(() => {
戻る {
変身: [
{
翻訳X: 翻訳X.値、
}、
{
翻訳Y: 翻訳Y.値、
}、
]、
};
});
戻る (
<PanGestureHandler onGestureEvent={onDrag}>
<AnimatedView style={[containerStyle, { top: -350 }]}>
<TapGestureHandler onGestureEvent={onDoubleTap} タップ数={2}>
<アニメーション画像
ソース={ステッカーソース}
sizeMode='contain'
style={[imageStyle, { 幅: 画像サイズ, 高さ: 画像サイズ }]}
/>
</TapGestureHandler>
</アニメーションビュー>
</PanGestureHandler>
);
}</pre>
<p>アプリは、Web と iOS 上で常に完璧に動作します。 iOS では正常に動作しますが、Web では動作しないため、疑念を感じました。変換スタイルが廃止されたため、Web 固有のスタイルを作成する方法を見つけようとしていますが、他の人がこの問題に遭遇した状況を見つけるのに苦労しています。本当の解決策があると信じていますが、私がそれを見逃しているだけかもしれません。 iOS では完璧に動作するのに、Web では動作しないので、本当に混乱しています。 </p>
<p>他にも同様の問題を抱えている人がいないか確認しようとしましたが、実際には関連するものは見つかりませんでした。また、コンソールで表示された警告を検索してみました。 </p>
<p><code>「transform」スタイルの配列値は非推奨になりました。 「scaleX(2)rotateX(15deg)」などのスペース区切りの文字列関数を使用してください。 </code></p>
<p>少なくとも React-Native に関連するものを検索したとき、関連するものは見つかりませんでした。 </p>
<p>ウェブ上でドラッグ可能なソリューションを見つけたいと思っています。 </p>
この問題は、
react-native-reanimated
のドキュメントを参照して解決しました。どうやらuseAnimatedGestureHandler
はonDoubleTap
で動作するため非推奨ではないようです。onDrag
は iOS でも正常に動作することは言うまでもありません。しかし、パン ジェスチャを扱うドキュメントで次のことを見つけました:
リーリーしたがって、
PanGestureHandler
とTapGestureHandler
を「react-native-gesture-handler」や「react-native-reanimated」からインポートする必要はありませんuseAnimatedGestureHandler
、「react-native-gesture-handler」からGesture
とGestureDetector
をインポートするだけです。Gesture
はuseAnimatedGestureHandler
を置き換え、GestureDetector
はPanGestureHandler
やTapGestureHandler
などのコンポーネントを置き換えます。また、
useSharedValue()
を使用して独自のcontextX
変数とcontextY
変数を作成する必要もあります。なぜなら、私の知る限り、onBegin()
andonChange()
コールバック関数には設定するコンテキストがありません。とにかく、修正されたコードは次のとおりです。これは Web と iOS の両方で完全に動作するようになりました:
リーリー