React Native(iOS)新手小白零基礎(chǔ)自學(xué)(十二)Native擴(kuò)展

前面看了一大段,看不懂,好亂?。。?!直接實(shí)戰(zhàn)開始吧。
1.創(chuàng)建一個(gè)Native模塊:獲得當(dāng)前屏幕尺寸Dimensions,并且提供注冊(cè)事件監(jiān)控屏幕方向變化。

首先,我們?cè)陧?xiàng)目工程中創(chuàng)建Native模塊類RCTDeviceExtension,繼承RCTBridgeModule協(xié)議:

![EB431DC7-F27F-46B6-A948-B0B7C69A37C6.png](http://upload-images.jianshu.io/upload_images/1712038-132bc558934715d6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

然后我們?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)問題暫未解決,暫不上傳了。。。等我解決后再上傳-_-!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容