Rumah  >  Soal Jawab  >  teks badan

React Native useAnimatedGestureHandler tidak dipanggil hanya dalam onStart di web

<p><strong>Sebelum saya sedar onStart() tidak dipanggil</strong></p> <p>Menggunakan PanGestureHandler di web dan cuba "menyeret" AnimatedView tidak berfungsi di web. Tiada ralat yang jelas, aplikasi dibina dengan baik dan tiada amaran dalam konsol semasa menyemak. </p> <p>Terdapat amaran yang membuatkan saya percaya ini mungkin punca masalah. Saya mendapat amaran pada konsol yang berbunyi: </p> <p><kod>nilai tatasusunan gaya "transform" tidak digunakan lagi. Sila gunakan fungsi rentetan terhad ruang, seperti "scaleX(2) rotateX(15deg)". </code></p> <p>Saya menggunakan AnimatedView dengan containerStyle untuk mengubah dan memindahkan objek apabila diseret. </p> <p><strong>Punca masalah</strong></p> <p>Jadi, saya meneliti masalah ini dengan lebih lanjut, cuba menyahpepijatnya, dan saya menyedari bahawa panggilan balik onStart() tidak dipanggil. Memandangkan panggilan balik onStart() tidak dipanggil, nilai konteks tidak pernah ditetapkan dan objek konteks kekal kosong secara keseluruhan. Ini membawa kepada masalah asal saya, tidak dapat menyeret objek. </p> <p>Walau bagaimanapun, ia masih akan berfungsi pada iOS. Atas sebab tertentu pada iOS panggilan balik onStart() dipanggil. Ini menyebabkan konteks diisi dan berfungsi dengan baik. </p> <p>Ini kod saya, ingat ini hanyalah komponen. Dalam direktori akar, saya mempunyai komponen GestureHandlerRootView yang membungkus keseluruhan aplikasi.</p> <pre class="brush:php;toolbar:false;">import { View, Image } daripada 'react-native'; import Animasi, { gunakanAnimatedStyle, useSharedValue, gunakanAnimatedGestureHandler, denganSpring, } daripada 'react-native-reanimate'; import { PanGestureHandler, TapGestureHandler } daripada 'react-native-gesture-handler'; const AnimatedImage = Animated.createAnimatedComponent(Imej); const AnimatedView = Animated.createAnimatedComponent(View); eksport fungsi lalai EmojiSticker ({ imageSize, stickerSource }) { skala constImage = useSharedValue(imageSize); const translateX = useSharedValue(0); const translateY = useSharedValue(0); const onDoubleTap = useAnimatedGestureHandler({ onActive: () => { if (scaleImage.value !== imageSize * 2) { skalaImage.value = skalaImage.value * 2; } lain { skalaImage.value = skalaImage.value / 2; } }, }); const onDrag = useAnimatedGestureHandler({ onStart: (acara, konteks) => { context.translateX = translateX.value; context.translateY = translateY.value; }, onActive: (acara, konteks) => { translateX.value = event.translationX + context.translateX; translateY.value = event.translationY + context.translateY; }, }); const imageStyle = useAnimatedStyle(() => { kembali { lebar: withSpring(scaleImage.value), ketinggian: withSpring(scaleImage.value), }; }); const containerStyle = useAnimatedStyle(() => { kembali { mengubah: [ { translateX: translateX.value, }, { translateY: translateY.value, }, ], }; }); kembali ( <PanGestureHandler onGestureEvent={onDrag}> <AnimatedView style={[containerStyle, { atas: -350 }]}> <TapGestureHandler onGestureEvent={onDoubleTap} numberOfTaps={2}> <Imej Animasi source={stickerSource} resizeMode='mengandungi' style={[imageStyle, { width: imageSize, height: imageSize }]} /> </TapGestureHandler> </AnimatedView> </PanGestureHandler> ); }</pre> <p><strong>顺便说一下,双击手势在 Web 和 iOS 上都完美工作。</strong> 我感到困惑,因为拖动在 iOS 上完美工作,但在 Web 上却不行。Penamatan gaya transformasi membuatkan saya cuba memikirkan cara untuk mencipta gaya khusus web, tetapi saya menghadapi masalah mencari situasi di mana orang lain menghadapi masalah ini. Saya percaya ada penyelesaian sebenar, saya mungkin merinduinya. Saya benar-benar keliru kerana ia berfungsi dengan sempurna pada iOS tetapi tidak di web. </p> <p>Saya cuba melihat sama ada orang lain mengalami masalah yang sama tetapi sebenarnya tidak menemui apa-apa yang berkaitan. Saya juga cuba mencari di konsol untuk amaran yang saya lihat. </p> <p><kod>nilai tatasusunan gaya "transform" telah ditamatkan. Sila gunakan fungsi rentetan terhad ruang, seperti "scaleX(2) rotateX(15deg)". </code></p> <p>Sekurang-kurangnya apabila saya mencari sesuatu yang berkaitan dengan React-Native, saya tidak menemui apa-apa yang berkaitan. </p> <p>Saya ingin mencari penyelesaian yang boleh diseret di web. </p>
P粉667649253P粉667649253452 hari yang lalu505

membalas semua(1)saya akan balas

  • P粉293550575

    P粉2935505752023-08-17 11:02:56

    Saya telah menyemaknyareact-native-reanimated的文档来解决了这个问题。显然,useAnimatedGestureHandler并没有被弃用,因为它在onDoubleTap中起作用,更不用说onDrag dan ia juga berfungsi dengan baik pada iOS.

    Tetapi dalam dokumentasi yang berkaitan dengan gerak isyarat kuali saya dapati ini:

    const pan = Gesture.Pan()
      .onBegin(() => {
        pressed.value = true;
      })
      .onChange((event) => {
        offset.value = event.translationX;
      })
      .onFinalize(() => {
        offset.value = withSpring(0);
        pressed.value = false;
      });

    Jadi, tidak perlu mengimport PanGestureHandlerTapGestureHandler,也不需要从'react-native-reanimated'中导入useAnimatedGestureHandler,只需要从'react-native-gesture-handler'中导入GestureGestureDetector daripada 'react-native-gesture-handler'.

    Gesture取代了useAnimatedGestureHandler,而GestureDetector取代了PanGestureHandlerTapGestureHandler dan komponen lain.

    Saya juga perlu menggunakan useSharedValue()创建自己的contextXcontextY变量,因为据我所知,onBegin()onChange()Fungsi panggil balik tiada konteks untuk ditetapkan.

    Apa pun, berikut ialah kod tetap, yang kini berfungsi dengan sempurna pada kedua-dua web dan iOS:

    import { View, Image } from 'react-native';
    import Animated, {
      useAnimatedStyle,
      useSharedValue,
      withSpring,
    } from 'react-native-reanimated';
    import { Gesture, GestureDetector } from 'react-native-gesture-handler';
    
    const AnimatedImage = Animated.createAnimatedComponent(Image);
    const AnimatedView = Animated.createAnimatedComponent(View);
    
    export default function EmojiSticker({ imageSize, stickerSource }) {
      const scaleImage = useSharedValue(imageSize);
      const translateX = useSharedValue(0);
      const translateY = useSharedValue(0);
      const contextX = useSharedValue(0);
      const contextY = useSharedValue(0);
    
      const onDoubleTap = Gesture.Tap().numberOfTaps(2)
        .onEnd(() => {
          if (scaleImage.value !== imageSize * 2) {
            scaleImage.value = scaleImage.value * 2;
          } else {
            scaleImage.value = scaleImage.value / 2;
          }
        });
      const onDrag = Gesture.Pan()
        .onBegin(() => {
          contextX.value = translateX.value;
          contextY.value = translateY.value;
        })
        .onChange((event) => {
          translateX.value = event.translationX + contextX.value;
          translateY.value = event.translationY + contextY.value;
        });
    
      const imageStyle = useAnimatedStyle(() => {
        return {
          width: withSpring(scaleImage.value),
          height: withSpring(scaleImage.value),
        };
      });
      const containerStyle = useAnimatedStyle(() => {
        return {
          transform: [
            {
              translateX: translateX.value,
            },
            {
              translateY: translateY.value,
            },
          ],
        };
      });
    
      return (
        <GestureDetector gesture={onDrag}>
          <AnimatedView style={[containerStyle, { top: -350 }]}>
            <GestureDetector gesture={onDoubleTap}>
              <AnimatedImage
                source={stickerSource}
                resizeMode="contain"
                style={[imageStyle, { width: imageSize, height: imageSize }]}
              />
            </GestureDetector>
          </AnimatedView>
        </GestureDetector>
      );
    }

    balas
    0
  • Batalbalas