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规定的固定写法(自己也不知道,反正照着葫芦画瓢就好了)?

 

我这里多写了一个,自己懵懂,是按照一个插件去写的,其实实现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那边设置,如: <DrawView transPos={{x:0,y:0}}/>,我这里是要传一个偏移位置,所以通过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<array.count; i++) {
        color = [RCTConvert UIColor:array[i][@"color"]];
        CGContextSetStrokeColorWithColor(context, color.CGColor);
        CGContextSetLineWidth(context, [RCTConvert CGFloat:array[i][@"stroke"]]);
        CGPoint aPoints[2];//坐标点
        aPoints[0] =CGPointMake([RCTConvert CGFloat:array[i][@"x1"]], [RCTConvert CGFloat:array[i][@"y1"]]);//坐标1
        aPoints[1] =CGPointMake([RCTConvert CGFloat:array[i][@"x2"]], [RCTConvert CGFloat:array[i][@"y2"]]);//坐标2
        CGContextAddLines(context, aPoints, 2);//添加线
        CGContextDrawPath(context, kCGPathStroke); //根据坐标绘制路径
      }
    }
  }
<span style="font-family: Arial, Helvetica, sans-serif;">}</span>


代码:

源码查看



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苏小败在路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值