react native 的组件仍是很少,有些也并不怎么好用,这时候就须要封装原生 UI 组件来供RN 使用了react
以前写过RN 与 native 的通讯 无非就是两种:ios
1 >>> RN->native react native 内部事件须要通知 native 调用 native 的方法(或者传递RN 中的数据到 native),这时候能够用新建一个 manager 之类的文件 RCT_EXPORT_MOUDLE() 暴露 native类 ,RCT_EXPORT_METHOD () 暴露 native 方法给 js 调用 ,在 js里经过 NativeMoudles.XXX 取得该 native 文件 而后调用方法(传递 js里的参数到 native )便可完成通讯动画
2 >>> native->RN native 发生的事件须要通知到js的时候 一种发送通知 self.bridge sendXXX 这种方法好像不经常使用 有警告,固然也能够用上面的那种采用 js主动调用 native, 在 native 方法里添加一个 block 回调,在 block 回调里把数据回传给 js. 或者就是下面的方法,导出 native 组件的方法给 jsui
下面开始封装原生ios组件atom
这里我封装的是一个相册浏览视图,PhotoView 继承自 UIView ,就按普通的自定义 View 来就能够了.url
而后有三点不一样的代理
1. >>> 声明一个RCTBubblingEventBlock 的属性,这是什么鬼 ? 就是你要导出的方法,命名以 on开头 好比 onTap,onClick自行发挥调试
2. >>> 若是须要在 js里给你的 UI 组件传值 ,赋值属性的话 ,暴露出来一个须要传值得属性: 如@property(nonatomic,strong)NSString ***blog
3. >>>若是须要导出方法的话, 声明一个 protocol ,代理方法 ,让你的代理去执行,为何要用代理呢 , 后面再说,下面看图: 自定义 UI 组件继承
注释已经很清楚了,没有什么须要解释的吧,须要的话,私聊哈
而后就是导出这个 UI 组件了
1 > 新建一个Manager,固然啦,你爱叫什么都行,通常以 manager 命名,继承自 RCTViewManger
2 > 遵照你刚才自定义视图的协议 做为他的代理 实现他的代理方法
3 > 重写-(UIView *)view 的方法,在该方法里 不要赋值什么属性,什么都不要干, alloc init 设置代理为 self 就 OK
4 > RCT_EXPORT_MOUDLE()导出模块 RCT_EXPORT_VIEW_PROPERTY(url,NSString)导出属性 RCT_EXPORT_VIEW_PROPERTY(onSingleTap,RCTBubblingEventBlock)导出方法 须要注意的是必定要写对属性名 和方法名 跟你自定义视图里的一致
5 > 若是是单纯的导出属性的话不须要代理什么的已经能够了 导出方法的话就要实现代理方法 在代理方法里 经过持有的自定义视图 赋值自定义视图的 block,导出方法,能够带一个 obj类型的参数, 下面看图
最后就是在 js里使用这个原生的 UI 组件了
首先新建一个 js 文件 用来做为导出的 UI 组件
如图所示: 利用 react native 的 requireNativeComponnent 来导出原生组件(参数1 为 native 的模块名称(类名),参数2 为 js中组件名称(类名))
1和2 是导出的组件名称 相同
3和4 是须要导出的当前 module 相同
5就是 native 中 RCT_EXPORT_MOUDULE("XXX")括号中的名称 若是为空就默认为 native 的类名
而后在须要用到的地方就能够 import 该js文件
其中 imgURL 就是 native组件须要的须要
onSingleTap 就是传递过来的 native 的事件
注意: 名称必定要跟 native 里定义的一致 在传递过来的参数里 e.nativeEvent.xxx 就是你在 native 传过来的参数
tips: 有一个比较坑的地方,就是在 js调试你原生 UI 事件的时候不要用 console.warn(),一直不会打印警告,不过也可能跟个人视图有关系,我添加的有动画,可能产生冲突