You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native Video低iOS版本(<16)失焦无法暂停问题求助

解决iOS 16以下版本useFocusEffect视频暂停失效问题

问题本质

useFocusEffect的清理函数在iOS 16及以下设备上,页面跳转或失焦时无法稳定触发,导致视频无法按预期暂停。这是旧版iOS对React Navigation焦点事件的处理逻辑存在兼容性差异,部分场景下焦点变更事件没有被正确捕获。

兼容解决方案

方案1:结合AppState监听补充控制

利用React Native的AppState监听应用前后台状态,和useFocusEffect形成互补,覆盖低版本iOS的焦点事件遗漏场景:

import { AppState } from 'react-native';
import { useFocusEffect } from '@react-navigation/native';
import React, { useCallback, useEffect, useState } from 'react';

const VideoPlayer = () => {
  const [appState, setAppState] = useState(AppState.currentState);
  
  // 保留原有useFocusEffect逻辑
  useFocusEffect(
    useCallback(() => {
      if (videoRef.current) {
        setPlaybackRate(1.0);
      }
      return () => {
        if (videoRef.current) {
          setPlaybackRate(0);
          console.log("videoRef!! ", elapsedTime);
        } else {
          console.log("Player Destroyed !! ", elapsedTime);
          console.log("Player Destroyed !! ", videoId, videoName);
          fetchWatchHistory(phoneNumber, videoId, videoName, elapsedTime, 1);
        }
      };
    }, [videoRef, elapsedTime])
  );

  // 新增AppState状态监听
  useEffect(() => {
    const handleAppStateChange = (nextAppState) => {
      // 应用切后台时强制暂停视频
      if (nextAppState === 'background' && videoRef.current) {
        setPlaybackRate(0);
      }
      // 应用回到前台且页面处于焦点时恢复播放
      if (nextAppState === 'active' && videoRef.current) {
        setPlaybackRate(1.0);
      }
      setAppState(nextAppState);
    };

    const subscription = AppState.addEventListener('change', handleAppStateChange);
    return () => subscription.remove();
  }, [videoRef]);

  // 组件其他逻辑...
};

方案2:用useIsFocused实时监听焦点状态

放弃依赖useFocusEffect的清理函数,改用useIsFocused钩子实时监听页面焦点状态,主动控制播放/暂停:

import { useIsFocused } from '@react-navigation/native';
import React, { useEffect } from 'react';

const VideoPlayer = () => {
  const isFocused = useIsFocused();

  useEffect(() => {
    if (!videoRef.current) return;
    
    if (isFocused) {
      setPlaybackRate(1.0);
    } else {
      setPlaybackRate(0);
      if (!videoRef.current) {
        fetchWatchHistory(phoneNumber, videoId, videoName, elapsedTime, 1);
      }
    }
  }, [isFocused, videoRef, elapsedTime]);

  // 组件其他逻辑...
};

方案3:直接监听页面导航事件

在当前页面监听导航的blur和focus事件,确保页面切换时必触发控制逻辑:

import { useNavigation } from '@react-navigation/native';
import React, { useEffect } from 'react';

const VideoPlayer = () => {
  const navigation = useNavigation();

  useEffect(() => {
    // 页面失焦时暂停
    const blurSubscription = navigation.addListener('blur', () => {
      if (videoRef.current) {
        setPlaybackRate(0);
        console.log("videoRef!! ", elapsedTime);
      } else {
        console.log("Player Destroyed !! ", elapsedTime);
        fetchWatchHistory(phoneNumber, videoId, videoName, elapsedTime, 1);
      }
    });

    // 页面获焦时恢复播放
    const focusSubscription = navigation.addListener('focus', () => {
      if (videoRef.current) {
        setPlaybackRate(1.0);
      }
    });

    return () => {
      blurSubscription();
      focusSubscription();
    };
  }, [navigation, videoRef, elapsedTime]);

  // 组件其他逻辑...
};

验证要点

  • 测试iOS 15及以下设备时,需覆盖页面跳转、应用切后台、锁屏、多任务切换等场景
  • 确保videoRef的引用始终有效,避免组件卸载后引用丢失导致逻辑失效

内容的提问来源于stack exchange,提问作者Crush Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 01:22:18