如何使用iOS / Objective-C中的UI组件桥从React Native发送点击事件

时间:2018-09-21 15:14:58

标签: objective-c react-native

我的应用程序需要在本地iOS SDK(Esri映射)中调用方法,并且我已经实现了使用以下代码从RN(0.55)跨桥向Android发送事件:

BaseEsriMap组件:

import React, { Component } from 'react';
import { requireNativeComponent, UIManager, findNodeHandle } from 'react-native';

const RNTMap = requireNativeComponent('RNTEsriMaps', null);

class BaseEsriMap extends Component {
  recenterMap = () => {
    console.log('Recenter requested');
    UIManager.dispatchViewManagerCommand(
      findNodeHandle(this.mapRef),
      UIManager.RNTEsriMaps.Commands.recenterMap,
      [],
    );
  };

  render() {
    return (
      <RNTMap
        style={ { flex: 1 } }
        ref={ (component) => { this.mapRef = component; } }
      />
    );
  }
}

export default BaseEsriMap;

RNTEsriMapsManager:

...
public class RNTEsriMapsManager extends ViewGroupManager<MapViewLayout> {
  public static final String REACT_CLASS = "RNTEsriMaps";

  public static final int COMMAND_RECENTER_MAP = 1;

  @Override
  protected MapViewLayout createViewInstance(ThemedReactContext reactContext) {
    MapViewLayout mapViewLayout = new MapViewLayout(reactContext);
    return mapViewLayout;
  }
...
  @Override
  public Map<String,Integer> getCommandsMap() {
    return MapBuilder.of(
            "recenterMap",
            COMMAND_RECENTER_MAP
            );
  }

  @Override
  public void receiveCommand(
        MapViewLayout esriMapView,
        int commandType,
        @Nullable ReadableArray args) {
    Assertions.assertNotNull(esriMapView);
    Assertions.assertNotNull(args);
    switch (commandType) {
        case COMMAND_RECENTER_MAP: {
            Log.d("Recenter", "COMMAND_RECENTER_MAP");
            return;
        }
        default:
            throw new IllegalArgumentException(String.format(
                    "Unsupported command %d received by %s.",
                    commandType,
                    getClass().getSimpleName()));
      }
  }
}

我相信应该将代码添加到我的RNTEsriMapsManager.m中。

#import "RNTEsriMapsManager.h"
#import "EsriMapView.h"

@implementation RNTEsriMapsManager

RCT_EXPORT_MODULE()

-(UIView*)view {
  EsriMapView *mapView = [[EsriMapView alloc] init];
  mapView.mapDelegate = self;
  return mapView;
}

// recenterMap implementation here?
@end

如何扩展代码以在iOS上执行相同的操作?

1 个答案:

答案 0 :(得分:1)

一种实现方法是公开一个方法:

#import "RNTEsriMapsManager.h"
#import "EsriMapView.h"


@interface RNTEsriMapsManager ()
@property (nonatomic, strong) EsriMapView *mapView;
@end

@implementation RNTEsriMapsManager

RCT_EXPORT_MODULE()
RCT_EXPORT_METHOD(recenterMap)
{
  NSLog(@"Method called to recenter map");
  [self.mapView mapViewsFunctionToRecenter];
}

-(UIView*)view {
  if (!self.mapView) {
    self.mapView = [[EsriMapView alloc] init];
    self.mapView.mapDelegate = self;
  }

  return self.mapView;
}

然后在您的JavaScript中,您可以在RNTMap const上将其作为函数调用:

import { NativeModules } from 'react-native';
const mapManager = NativeModules.RNTEsriMapsManager;
mapManager.recenterMap();

我将地图视图设为一个属性,以便可以在该方法中访问它,因为我假设它具有可用于更新它的方法。