react native之App集成以及高度自适应

集成

与现有App集成,以及高度适应问题,官方文档中都有说明,单拉一篇文章出来,主要是想记录一下其中的问题点,给大家做些参考。

集成到现有App,无非是把react界面放到现有App中的某个页面中,那么第一点是要把react native加到现有工程,第二点创建RCTRootView并添加到某页面。

react native添加到现有工程,有两种方式:

1、使用cocoapods,自动化管理;
2、手工集成,即将react native各个子工程手动添加到项目中;

但是,在此之前,还有一件至关重要的事:下载react native工程

react native使用node.js作为工程集成环境,包管理使用npm工具,所以这一步也比较简单:

//在现有App工程目录中创建package.json文件,执行npm install:
{
  "name": "reactDemo",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start"
  },
  "dependencies": {
    "react": "^15.2.1",
    "react-native": "^0.29.2"
  }
}

当前目录就会创建node_modules,react native所有依赖项都存在此目录中。

使用cocoapods集成比较方便:

//创建podfile,配置工程依赖项,注意:path路径要设置自己的node_modules正确路径

target 'App工程名称' do

  pod 'React', :path => './node_modules/react-native', :subspecs => [
    'Core',
    'RCTText',
    'RCTWebSocket', # needed for debugging
    # Add any other subspecs you want to use in your project
    'RCTImage',
    'RCTNetwork',
    'RCTActionSheet',
    'RCTGeolocation',
    'RCTLinkingIOS',
    'RCTVibration',
    'RCTSettings',
  ]

end

执行: pod install, 即可集成react native到现有工程。

手动添加react native,就要麻烦一下,进入node_modules目录查找相应react工程,即project,将project添加到现有工程中即可。

下一步,创建react页面,并作为子页面添加到现有项目中:

    NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];

    jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
    
    _rctView = [[RCTRootView alloc] initWithBundleURL: jsCodeLocation moduleName:@"reactDemo" initialProperties:@{} launchOptions:nil];
    
    [self.view addSubview: _rctView];

到这一步,算是整体集成完毕,可以启动服务看页面是否能正常展示。

react高度适应

react页面高度是不定的,这就给react页面的父页面设定带来一些问题。官方也给出了解决方案,就是父页面使用UIScrollView,并监听react页面高度变化,使父页面随react页面变化而变化。

设置监听RCTRootView的高度变化:


    _rctView.delegate = self;
    _rctView.sizeFlexibility = RCTRootViewSizeFlexibilityHeight;

#pragma mark - RCTRootViewDelegate
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView {

    CGRect newFrame = rootView.frame;
    newFrame.size = rootView.intrinsicSize;
    
    rootView.frame = newFrame;
    self.view.frame = newFrame;
    
    if (self.delegate) {
        [self.delegate didChangeHeight: newFrame.size.height];
    }
}    

ok,集成和高度适应都完毕了,下来还有什么问题?

touchable与UIScrollView事件冲突问题

这里说的事件冲突,倒不是说UIScrollView截获了Touchable的点击事件,而是Touchable会把UIScrollView的滚动事件误认为是点击事件。所以造成的现象就是,当滚动UIScrollView时,同时会出发Touchable点击事件,这种体验糟糕的不要不要的。

react native自身也封装了ScrollView,在使用react native的ScrollView时不会存在这个问题,明显react native发现并解决了该问题。react native的点击事件又必须依赖Touchable,我们又不能使用react native的ScrollView,所以这个问题不能靠框架解决。

解决思路:

Touchable是完全依赖事件模拟的点击操作,发生混乱的原因是UIScrollView滚动相关事件传递给了js侧的Touchable,所以只要把滚动的相关事件屏蔽调就可以实现目标。

解决方法:

RCTRootView是native与js侧的桥梁,所有UI触摸事件都是通过该View传递给js,该View有个cancelTouches方法,用来取消当前的触摸事件,所以,只要在scrollViewWillBeginDragging方法中调用[_rctView cancelTouches]即可。

交互与扩展

既然集成react native到本地项目中,那么必然还存在两者之间的交互。react native核心技术是javascriptCore,交互必然也是通过它了。与WebView不同,javascriptCore是独立存在项目中,整个react native都是通过一个单独的jscontext建立之间的联系,也就无法截获WebView的请求消息进行通信。好消息是,无论旧的WebView方式还是新的javascriptCore方式,只需要封装一下甚至无需封装,就可以将旧的jsbridge接口移植到react native项目中。

有关jsbridge和javascriptCore可以参考之前的文章:

H5与native之间的通信

javascriptCore 详解

如何注入到react native可以参考这篇文章:

react native之OC与js之间交互

如何注入到react native中的WebView,可以参考这篇文章:

react native之WebView中注入js接口

如何让你的项目可以随意更换react native服务器地址,可以参考这个工具:

react-native-debug-server-host

需要注意一点:react native的jscontext是在子线程中创建执行,所以如果你的接口中有UI的操作,需要手动指定到UI线程执行。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,591评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,448评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,823评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,204评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,228评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,190评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,078评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,923评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,334评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,550评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,727评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,428评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,022评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,672评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,826评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,734评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,619评论 2 354

推荐阅读更多精彩内容