react native 的组件还是不多,有些也并不怎么好用,这时候就需要封装原生 UI 组件来供RN 使用了

之前写过RN 与 native 的通信 无非就是两种:

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 组件的方法给 js

下面开始封装原生ios组件

这里我封装的是一个相册浏览视图,PhotoView 继承自 UIView ,就按普通的自定义 View 来就可以了.

然后有三点不同的

1. >>> 声明一个RCTBubblingEventBlock 的属性,这是什么鬼 ? 就是你要导出的方法,命名以 on开头 比如 onTap,onClick自行发挥

2. >>> 如果需要在 js里给你的 UI 组件传值 ,赋值属性的话 ,暴露出来一个需要传值得属性: 如@property(nonatomic,strong)NSString ***

3. >>>如果需要导出方法的话, 声明一个 protocol ,代理方法 ,让你的代理去执行,为什么要用代理呢 , 后面再说,下面看图: 自定义 UI 组件

react native 封装 iOS 原生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类型的参数, 下面看图 

react native 封装 iOS 原生UI 组件react native 封装 iOS 原生UI 组件

最后就是在 js里使用这个原生的 UI 组件了 

首先新建一个 js 文件 用来作为导出的 UI 组件

react native 封装 iOS 原生UI 组件

如图所示: 利用 react native 的 requireNativeComponnent 来导出原生组件(参数1 为 native 的模块名称(类名),参数2 为 js中组件名称(类名))

1和2 是导出的组件名称 相同

3和4 是需要导出的当前 module 相同

5就是 native 中 RCT_EXPORT_MOUDULE("XXX")括号中的名称  如果为空就默认为 native 的类名

然后在需要用到的地方就可以 import 该js文件

react native 封装 iOS 原生UI 组件

其中 imgURL 就是 native组件需要的需要 

onSingleTap 就是传递过来的 native 的事件

注意: 名称一定要跟 native 里定义的一致 在传递过来的参数里 e.nativeEvent.xxx 就是你在 native 传过来的参数

tips: 有一个比较坑的地方,就是在 js调试你原生 UI 事件的时候不要用 console.warn(),一直不会打印警告,不过也可能跟我的视图有关系,我添加的有动画,可能产生冲突

 

相关文章: