如何在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
相关产品推荐
相关产品推荐

