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

如何在React Native的Swift原生组件中指定Props并传递视频URL?

实现方案

一、Swift原生端改造:支持接收视频URL Prop

1. 升级VideoPlayerView与TweetViewManager

修改Swift代码,添加可被React Native识别的属性,并实现属性变化时的视频加载逻辑:

import UIKit
import AVFoundation

@objc(TweetViewManager)
class TweetViewManager: RCTViewManager {
    // 定义RN可传递的videoURL属性,值变化时同步给视图
    @objc var videoURL: String? {
        didSet {
            (view() as? VideoPlayerView)?.videoURLString = videoURL
        }
    }

    override func view() -> UIView {
        return VideoPlayerView()
    }

    override static func requiresMainQueueSetup() -> Bool {
        return true
    }

    // 暴露组件名称给RN
    override static func moduleName() -> String! {
        return "TweetView"
    }
}

class VideoPlayerView: UIView {
    private var player: AVPlayer?
    private var playerLayer: AVPlayerLayer?
    
    // 接收RN传递的视频URL字符串
    @objc var videoURLString: String? {
        didSet {
            setupVideoPlayer(with: videoURLString)
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    private func setupVideoPlayer(with urlString: String?) {
        // 清理旧播放器层
        playerLayer?.removeFromSuperlayer()
        
        guard let urlString = urlString, 
              let videoURL = URL(string: urlString.trimmingCharacters(in: .whitespaces)) 
        else { return }
        
        player = AVPlayer(url: videoURL)
        playerLayer = AVPlayerLayer(player: player)
        playerLayer?.frame = bounds
        layer.addSublayer(playerLayer!)
        
        player?.play()
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        playerLayer?.frame = bounds
    }
}

2. 注册原生组件

在AppDelegate.swift的RCTBridgeDelegate实现中,将TweetViewManager添加到桥接模块列表:

import React

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // ...其他初始化代码
    let bridge = RCTBridge(delegate: self, launchOptions: launchOptions)
    // ...
    return true
}

func extraModules(for bridge: RCTBridge!) -> [RCTBridgeModule]! {
    return [TweetViewManager()]
}

二、React Native端改造:传递视频URL Prop

修改RN代码,直接给TweetView组件传递videoURL属性:

import React from 'react';
import { StyleSheet, View } from 'react-native';
import { requireNativeComponent } from 'react-native';

const TweetView = requireNativeComponent('TweetView');

const App = () => {
  return (
    <View style={styles.container}>
      <TweetView
        style={{height: 200, width: 200}}
        videoURL="https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default App;

核心要点

  • Swift中用@objc修饰属性,确保React Native可以识别并传递值;
  • 通过didSet监听属性变化,触发视频播放器的重新初始化;
  • 处理URL字符串的空格,避免解析失败;
  • 必须在ViewManager中实现moduleName(),保证RN能正确关联到原生组件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:19:53