• 封装IOS原生组件——导出组件事件到RN端使用


    导出IOS原生组件的事件到RN端的步骤。

    1、在IOS组件的头文件声明一个事件属性。

    2、在RN组件桥接类里面导出这个事件属性。

    3、在IOS原生端通过定义的事件属性发送事件到RN端。

    4、在RN端封装IOS原生组件事件。

    1、在IOS组件的头文件声明一个事件属性

    TestReactNativeView.h

    //
    //  TestReactNativeView.h
    //  NativeCommunicationDemo
    //
    //  Created by chenlw on 2019/4/10.
    //  Copyright © 2019 Facebook. All rights reserved.
    //
     
    #import <UIKit/UIKit.h>
    #import "React/RCTComponent.h"
     
    NS_ASSUME_NONNULL_BEGIN
     
    @interface TestReactNativeView : UIView
    // type操作类型
    @property(nonatomic,weak) NSString * type;
     
    //如果使用assign会导致线程锁死,使用weak弱引用就没有问题
    //@property(nonatomic,assign) UITextView *textView;
    @property(nonatomic,weak) UITextView *textView;
     
    // 声明一个事件属性,导出给RN端使用
    @property(nonatomic, copy) RCTBubblingEventBlock onFaceDetection;
     
    @end
     
    NS_ASSUME_NONNULL_END

    2、在RN组件桥接类导出这个事件属性

    TestReactNativeViewManager.m

    //
    //  TestReactNativeViewManager.m
    //  NativeCommunicationDemo
    //
    //  Created by chenlw on 2019/4/10.
    //  Copyright © 2019 Facebook. All rights reserved.
    //
     
    #import "TestReactNativeViewManager.h"
    #import "TestReactNativeView.h"
     
    @implementation TestReactNativeViewManager
     
     
    //导出桥接宏标记
    RCT_EXPORT_MODULE()
     
    //导出RN组件的属性
    RCT_EXPORT_VIEW_PROPERTY(type, NSString)
     
    //导出RN组件的事件
    RCT_EXPORT_VIEW_PROPERTY(onFaceDetection, RCTBubblingEventBlock)
     
    - (UIView *)view
    {
        //创建组件实例
        TestReactNativeView * viewInstance =[[TestReactNativeView alloc] init];
        return viewInstance;
    }
     
    @end

    3、在IOS原生端通过定义的事件属性发送事件到RN端

    模拟场景:在IOS原生自定义组件上添加一个按钮,点击按钮的时候,往RN发送事件。

    这里,我们通过一个按钮的点击事件来发送事件到RN端。

    TestReactNativeView.m

    //
    //  TestReactNativeView.m
    //  NativeCommunicationDemo
    //
    //  Created by chenlw on 2019/4/10.
    //  Copyright © 2019 Facebook. All rights reserved.
    //
     
    #import "TestReactNativeView.h"
     
    //ReactNative封装IOS原生组件,这里编写一个测试用的组件类
    @implementation TestReactNativeView
     
    /*
     // Only override drawRect: if you perform custom drawing.
     // An empty implementation adversely affects performance during animation.
     - (void)drawRect:(CGRect)rect {
     // Drawing code
     }
     */
     
    - (instancetype)init
    {
        //初始化组件
        self = [super init];
        if (self) {
            self.backgroundColor = [UIColor redColor];
        }
        
        //创建一个文本组件
        UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(20,20,300,40)];
        //设置文字
        textView.text = @"IOS原生组件";
        //设置字体大小
        [textView setFont:[UIFont systemFontOfSize:20]];
        //添加文件组件
        [self addSubview:textView];
        
        self.textView = textView;
        
        //创建一个按钮组件
        UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem];
        button.frame = CGRectMake(20, 80, 100, 40);
        [button setTitle:@"发送事件到RN" forState:UIControlStateNormal];
    //    [button addTarget:self action:@selector(sendEventToReactNative) forControlEvents:UIViewNoIntrinsicMetric];
        /**
         * addTarget:目标(让谁做这个事情)
         * action:方法(做什么事情-->方法)
         * forControlEvents:事件
         */
        [button addTarget:self action:@selector(sendEventToReactNative:) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:button];
        //[self bringSubviewToFront:button];
        
        return self;
    }
     
    //重写设置属性方法,当RN端设置type属性,就会调用这个方法
    -(void)setType:(NSString *)type{
        NSLog(@"setType");
        self.textView.text = type;
        //self.type = type;
    }
     
    //按钮的响应事件
    - (void)sendEventToReactNative:(UIButton *)button{
        NSLog(@"sendEventToReactNative");
        //往RN端发送事件
        self.onFaceDetection(@{@"faceBase64":@"IOS原生端回传的数据"});
    }
     
     
    @end

    4、在RN端封装IOS原生组件事件

    在RN组件内部,对这个事件进行封装处理,过滤掉对RN端无用的参数。

    'use strict';
    import React, {Component} from 'react';
    import PropTypes from 'prop-types';
    import {
        requireNativeComponent,
        View,
    } from 'react-native';
     
    const TestReactNativeView = requireNativeComponent('TestReactNativeView', TestReactNativeViewComponent
        , {nativeOnly: {}});
     
    //对封装的组件进行二次封装
    class TestReactNativeViewComponent extends Component {
     
        constructor(props) {
            super(props);
        }
     
        /**
         * 对IOS组件的事件进行处理,解析对RN端有用的参数
         * @param event
         * @private
         */
        _onFaceDetection = (event) => {
            if (!this.props.onFaceDetection) {
                return;
            }
            console.log('');
            console.log('_onFaceDetection');
            console.log(event.nativeEvent);
            this.props.onFaceDetection(event.nativeEvent.faceBase64);
        };
     
        render() {
            return (
                <TestReactNativeView
                    {...this.props}
                    onFaceDetection={this._onFaceDetection}
                />
            );
        }
    }
     
    TestReactNativeViewComponent.propTypes = {
        type: PropTypes.string,
        onFaceDetection: PropTypes.func,
        ...View.propTypes,
    };
     
    //导出二次封装的组件
    module.exports = TestReactNativeViewComponent;

    5、测试页面

    import React, {Component} from 'react';
    import {Dimensions, StyleSheet, View} from 'react-native';
    import TestReactNativeView from './TestReactNativeView';
     
    const screenWidth = Dimensions.get('window').width;
     
    /**
     * IOS原生组件封装,注意RN端设置组件的宽度和高度,这样组件才能显示。
     */
    export default class TestReactNativeViewExample extends Component {
     
        static navigationOptions = {
            headerTitle: 'IOS原生组件封装example',
        };
     
        constructor(props, context) {
            super(props, context);
        }
     
     
        render() {
     
            return (
                <View style={styles.container}>
                    <TestReactNativeView
                        style={{
                            flex: 1,
                             screenWidth,
                        }}
                        type={'type from react-native'}
                        onFaceDetection={(faceBase64) => {
                            console.log('');
                            console.log('TestReactNativeViewExample.TestReactNativeView');
                            console.log(faceBase64);
                            alert('RN端接收到IOS原生端发送的事件:'+faceBase64);
                        }}
                    />
                </View>
            )
        }
     
     
    }
     
    const styles = StyleSheet.create({
        container: {
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
        }
    });

    6、运行效果

  • 相关阅读:
    uva 532 Dungeon Master
    hrbeu 哈工程 Tunnels
    poj 1088 滑雪
    hrbeu 哈工程 Eular Graph
    uva 567 Risk
    hrbeu 哈工程 Minimum time
    产品要不要做先回答的10个问题
    用icacls命令行给目录赋权
    SQL Server的FileStream和FileTable
    cygwin 离线安装包(包括vim,ssh,scp)
  • 原文地址:https://www.cnblogs.com/itgezhu/p/13439616.html
Copyright © 2020-2023  润新知