React Native(iOS)新手小白零基础自学(十二)Na
2016-06-12 本文已影响613人
神魔狼
前面看了一大段,看不懂,好乱啊!!!直接实战开始吧。
1.创建一个Native模块:获得当前屏幕尺寸Dimensions,并且提供注册事件监控屏幕方向变化。
首先,我们在项目工程中创建Native模块类RCTDeviceExtension,继承RCTBridgeModule协议:
![EB431DC7-F27F-46B6-A948-B0B7C69A37C6.png](https://img.haomeiwen.com/i1712038/132bc558934715d6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)然后我们在index.ios.js里:
var React = require('react-native');
var {
AppRegistry,
StyleSheet,
View,
Text
} = React;
//立即执行
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);
结果:说明RCTDeviceExtension模块已经被加载到模块配置中了,同时在JavaScript模块中生成了DeviceExtension对象
2D0FB06D-5DEB-41B5-9F35-204129D207CC.png然后,开始实现模块方法。
在RCTDeviceExtension.m文件中添加如下代码
#import "RCTDeviceExtension.h"
#import "RCTUtils.h"
#import "RCTEventDispatcher.h"
#import "RCTConvert.h"
static NSDictionary *CurrentDimensions(){
//提供当前屏幕的尺寸
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;
//向系统注册模块。 ()内不填,会默认使用类名来作为模块名
RCT_EXPORT_MODULE();
- (instancetype)init
{
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
return self;
}
/*
常量导出
如下,则可以在JavaScript中直接访问字典的key值来访问字典对象
*/
- (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;
//发送设备相关的事件,例如地理定位和屏幕旋转
[_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来作为回调函数,此时只需要将一个NSArray对象传入块函数执行即可
*/
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');//屏幕旋转
DeviceExtension.getCurrentDimensions((error, dimensions) => {
console.log(dimensions);
});
var subscription = RCTDeviceEventEmitter.addListener('orientationDidChange', (dimensions) => {
console.log(dimensions);
});
最后若要把模块做成第三方组件的话,还要做些操作。这里我遇到了点问题暂未解决,暂不上传了。。。等我解决后再上传-_-!!