RCTVideoPlayer
假定原生組件是一個View,在ios端封裝該View
1.1 導入頭文件 <React/RCTComponent.h>
1.2 導入原生組件頭文件,本例子是?"TTAVPlayer.h"
1.3 引入js層傳入的block 事件屬性
RCTVideoPlayer.h
#import#import
#import "TTAVPlayer.h"
@interface RCTVideoPlayer : TTAVPlayerView
@property (nonatomic, copy) RCTBubblingEventBlock onBack;
@property (nonatomic, copy) RCTBubblingEventBlock onPlayError;
@property (nonatomic, copy) RCTBubblingEventBlock onPause;
@property (nonatomic, copy) RCTBubblingEventBlock onEnd;
@property (nonatomic, copy) RCTBubblingEventBlock onPlay;
@end
2.1 導入"RCTVideoPlayerManager.h"和<React/UIView+React.h>
2.2 init該View,并初始化js層設置的屬性
2.3 如果該View有設置代理,實現代理方法并向js層發通知以執行額外操作
#import "RCTVideoPlayer.h"#import "RCTVideoPlayerManager.h"#import@implementation RCTVideoPlayer
- (id)init
{
self = [super initWithFrame:CGRectZero withViewMode:TTAVPlayerViewNormalMode];
[super setDelegate:self];
return self;
}
- (void)setSrc:(NSString *)src {
NSLog(@"set src -> %@", src);
[super setVideoUrl:src];
}
- (void)backButtonGetTap:(BOOL)isFullScreen {
if(self.onBack && !isFullScreen){
self.onBack(@{@"isFullScreen": @(isFullScreen)});
}
}
RCTVideoPlayerManager
1.1 繼承RCTViewManager
#import<React/RCTViewManager.h>
#import "TTAVPlayer.h"
@interface RCTVideoPlayerManager : RCTViewManager
@end
2.1 聲明該class屬性共享
RCT_EXPORT_MODULE();
RCT_EXPORT_VIEW_PROPERTY(placeholderImage, NSString) ? 值屬性
RCT_EXPORT_VIEW_PROPERTY(onPlay, RCTBubblingEventBlock) ?事件屬性
事件屬性與View中的事件屬性相對應,實現原生向js層通信
2.2 初始化view(每個manager都有一個view)
- (UIView *)view
{ ? ?return [[RCTVideoPlayer alloc] init]; ? }
2.3 導出方法給js層調用
RCT_EXPORT_METHOD(play: (nonnull NSNumber *)reactTag) { [self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary*viewRegistry) {
UIView *view = viewRegistry[reactTag];
if (![view isKindOfClass:[RCTVideoPlayer class]]) {
RCTLog(@"expecting UIView, got: %@", view);
}
else {
RCTVideoPlayer *player = (RCTVideoPlayer *)view;
[player play];
}
}];
}
在js主動要求更新原生UI層的事件中,需要注意兩點,
1是使用[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary*viewRegistry) {}]來更新UI,該方法需要導入<React/RCTUIManager.h>
2是該方法需要特定的線程執行,如下
- (dispatch_queue_t)methodQueue
{
return self.bridge.uiManager.methodQueue;
}
js
導出UI組件
import { requireNativeComponent } from'react-native';
class VideoPlayer extends Component {
render() {
return <RCTVideoref="native" {...this.props} onPlayError={this.onPlayError}/>;
}
}
constRCTVideo =requireNativeComponent('RCTVideoPlayer',VideoPlayer);
export defaultVideoPlayer;
需要注意
1.1 class類似一般的react class
1.2 constructor(...args) {}
1.3 staticpropTypes= {
...View.propTypes,
src: PropTypes.string.isRequired,
onPlayError: PropTypes.func
};
1.4 js層調用原生方法
play= (url,isCache,title) => {
if(Platform.OS =='android') {
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(this),
UIManager.RCTVideoPlayer.Commands.play,
[url,isCache,title]
);
}else{
const{ VideoPlayerManager } = NativeModules;
VideoPlayerManager.play(ReactNative.findNodeHandle(this));
}
};