React-Native自定义view显示(原生端)

参考:http://blog.csdn.net/pz789as/article/details/52448048


自定义view: 自己写原生的view显示在RN界面上。


这次主要是项目需要绘制一张大图,里面有很多节点和线,如果使用单纯RN提供的view去做,需要的内存不够(量级在K以上),所以需要想办法在一个view中画所有的点和线。


自己在想的过程中,也去找了一些相关的RN插件,一个是react-native-svg,很好的插件,由于我需要动态更改节点和线的位置,这个插件不能很好的展示,所以放弃了。另外找到一个办法,这个其实就是svg提示,因为svg就是封装了RN自带的ART组件,该组件是RN提供,可以绘制各种图形,虽然可以变换位置等,也有很大弊端,不能使用setNativeProps函数,这个比较要命。因为频繁更新,不用这个函数很容易卡死。


最后辗转了各个网页,实在没办法打算自己写一个。


还好RN留下的借口很牛逼,可以嵌入各种自己写的原生代码。跟着教程写的,具体操作可以看下面网址:

点击打开链接


这里简单说下重点,因为当时自己看的时候也是没看懂(主要是这个api直接拿RNMap去举例,并没有其他的)

1,在xcode里面创建2个类,分别RCT***.h .m 和 RCT***Manager.h .m,这貌似是RN规定的固定写法(自己也不知道,反正照着葫芦画瓢就好了)?

React-Native自定义view显示(原生端)_第1张图片 

我这里多写了一个,自己懵懂,是按照一个插件去写的,其实实现drawRect可以写在RCTDrawView里面,我多写了一步;


2,Manager类需要继承 RCTViewManager

//  RCTDrawViewManager.h

#import "RCTViewManager.h"
@interface RCTDrawViewManager : RCTViewManager
@end
另一个就继承UIView就可以了。关键点是Manager这个,它相当于是原生和RN的桥梁,如果做过RN的原生模块就知道,和模块类似。

@implementation RCTDrawViewManager

RCT_EXPORT_MODULE();
@synthesize bridge = _bridge;

- (UIView *)view
{
  return [[RCTDrawView alloc] init];
}

RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor);
RCT_EXPORT_VIEW_PROPERTY(drawData, NSDictionary);
RCT_EXPORT_VIEW_PROPERTY(transPos, CGPoint);
RCT_EXPORT_VIEW_PROPERTY(scaleValue, CGPoint);
//RCT_CUSTOM_VIEW_PROPERTY(transPos, TransPos, RCTDrawView)
//{
//  [view setTransPos:json ? [RCTConvert TransPos:json] : defaultView.transPos];
//}

- (dispatch_queue_t)methodQueue
{
  return dispatch_get_main_queue();
}

@end

RCT_EXPORT_MODULE 导出模块,可以加个参数,字符串,标识这个模块的名称

RCT_EXPORT_VIEW_PROPERTY 导出属性,可以在js那边设置,如: ,我这里是要传一个偏移位置,所以通过JSON的格式传递,很多复杂的数据都可以这样传递,我的drawData就是,传到这边之后可以通过RCTConvert去转换成NSDictionary,当然RN也给我们封装了些常用的,如CGPoint,CGRect等等,可以去RCTConvert中查看,很丰富。

methodQueue 这个是指定线程,因为RN规定渲染需要在主线程中,所以添加这一句话,标识运行在哪个线程中,有很多第三方SDK可能需要这个设定,比如语音识别。


3,RCTDrawVIew里面主要说一点,就是在Manager里面定义的属性,需要在这个里面实现,或者说接收,比如我自己定义的

- (void)setBackgroundColor:(UIColor *)backgroundColor
{
  if ([_backgroundColor isEqual:backgroundColor]) {
    return;
  }
  
  _backgroundColor = backgroundColor;
  [self layoutSubviews];
}

-(void)setTransPos:(CGPoint)transPos
{
  self.drawView.transPos = transPos;
  [self layoutSubviews];
}

-(void)setScaleValue:(CGPoint)scaleValue
{
  self.drawView.scaleValue = scaleValue;
  [self layoutSubviews];
}

-(void)setDrawData:(NSDictionary *)drawData
{
  self.drawView.drawData = drawData;
  [self layoutSubviews];
}

名称都是一一对应的,前面加一个set就可以了。每次在js端设置了属性变更,就会触发这里的set函数,然后就可以做你想做的任何事情了。

我是要更新drawRect,所以要手动的设置 [self.drawViewsetNeedsDisplay]; ,这样一来,就可以更新drawRect里面的内容啦


4,下面看看解析drawData,主要是RCTConvert去转换。

NSArray * orderKey = [RCTConvert NSArray:_drawData[@"order"]];
  for (NSString *key in orderKey) {
    NSArray* array = [RCTConvert NSArray:_drawData[key]];
    if ([key containsString:@"lines"]){
      for (int i=0; i
  }
}


代码:

源码查看



你可能感兴趣的:(React-Native,IOS)