前面看了一大段,看不懂,好亂?。。?!直接實(shí)戰(zhàn)開始吧。
1.創(chuàng)建一個(gè)Native模塊:獲得當(dāng)前屏幕尺寸Dimensions,并且提供注冊(cè)事件監(jiān)控屏幕方向變化。
首先,我們?cè)陧?xiàng)目工程中創(chuàng)建Native模塊類RCTDeviceExtension,繼承RCTBridgeModule協(xié)議:


然后我們?cè)趇ndex.ios.js里:
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
View,
Text
} = React;
//立即執(zhí)行
var immediateID = setImmediate(function(){
console.log(require('NativeModules'));
});
var app = React.createClass({
render:function(){
return(
<View>
</View>
);
},
});
var styles = StyleSheet.create({
});
AppRegistry.registerComponent('RNOldVersionES5', () => app);
結(jié)果:說明RCTDeviceExtension模塊已經(jīng)被加載到模塊配置中了,同時(shí)在JavaScript模塊中生成了DeviceExtension對(duì)象

2D0FB06D-5DEB-41B5-9F35-204129D207CC.png
然后,開始實(shí)現(xiàn)模塊方法。
在RCTDeviceExtension.m文件中添加如下代碼
#import "RCTDeviceExtension.h"
#import "RCTUtils.h"
#import "RCTEventDispatcher.h"
#import "RCTConvert.h"
static NSDictionary *CurrentDimensions(){
//提供當(dāng)前屏幕的尺寸
CGFloat width = MIN(RCTScreenSize().width, RCTScreenSize().height);
CGFloat height = MAX(RCTScreenSize().width, RCTScreenSize().height);
CGFloat scale = RCTScreenScale();
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
width = MAX(RCTScreenSize().width, RCTScreenSize().height);
height = MIN(RCTScreenSize().width, RCTScreenSize().height);
}
return @{@"width":@(width),
@"height":@(height),
@"scale":@(scale)};
}
@implementation RCTDeviceExtension
@synthesize bridge = _bridge;
//向系統(tǒng)注冊(cè)模塊。 ()內(nèi)不填,會(huì)默認(rèn)使用類名來作為模塊名
RCT_EXPORT_MODULE();
- (instancetype)init
{
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
return self;
}
/*
常量導(dǎo)出
如下,則可以在JavaScript中直接訪問字典的key值來訪問字典對(duì)象
*/
- (NSDictionary *)constantsToExport
{
return @{@"EVENT_ORIENTATION":@"orientationDidChange"};
}
#pragma mark - Notification Selector
- (void)orientationDidChange:(id)noti
{
//通過RCTEventDispatcher將事件orientationDidChange通知到JavaScript,這里要引入RCTEventDispatcher頭文件。
//- (void)sendDeviceEventWithName:(NSString *)name body:(id)body;
//發(fā)送設(shè)備相關(guān)的事件,例如地理定位和屏幕旋轉(zhuǎn)
[_bridge.eventDispatcher sendDeviceEventWithName:@"orientationDidChange"
body:@{@"Orientation":UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation) ? @"Landscape":@"Portrait",
@"Dimensions":CurrentDimensions()}];
}
#pragma mark - Public APIs
/*
RCT_EXPORT_METHOD(js_name, method) 暴露模塊方法
一般情況下,我們都使用RCTResponseSenderBlock來作為回調(diào)函數(shù),此時(shí)只需要將一個(gè)NSArray對(duì)象傳入塊函數(shù)執(zhí)行即可
*/
RCT_EXPORT_METHOD(getCurrentDimensions:(RCTResponseSenderBlock)callback) {
callback(@[[NSNull null], CurrentDimensions()]);
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end
然后在ios.js中使用:
var DeviceExtension = require('NativeModules').DeviceExtension;//屏幕尺寸
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');//屏幕旋轉(zhuǎn)
DeviceExtension.getCurrentDimensions((error, dimensions) => {
console.log(dimensions);
});
var subscription = RCTDeviceEventEmitter.addListener('orientationDidChange', (dimensions) => {
console.log(dimensions);
});
最后若要把模塊做成第三方組件的話,還要做些操作。這里我遇到了點(diǎn)問題暫未解決,暫不上傳了。。。等我解決后再上傳-_-!!