将事件从IOS发送到JS

时间:2016-06-20 08:36:56

标签: javascript ios xcode react-native

我试图重复Facebook React-Native示例,但有点麻烦,我的Js代码没有从Objective-C获取事件。从JS到Objective-C的活动非常完美,我花了好几个小时试图发现它出了问题。任何人都可以找到myistake的地方吗?

InputTextFieldManager.h

@interface InputTextFieldManager : RCTViewManager <RCTBridgeModule>
@end

InputTextFieldManager.m

#import "InputTextFieldManager.h"

#import "InputTextFieldView.h"
#import "RCTBridge.h"

@interface InputTextFieldManager () <UITextFieldDelegate>

@end

@implementation InputTextFieldManager

@synthesize bridge = _bridge;

RCT_EXPORT_MODULE()

RCT_EXPORT_VIEW_PROPERTY(shouldChangeCharacters, RCTBubblingEventBlock)

RCT_EXPORT_VIEW_PROPERTY(titleLabelText, NSString *)
RCT_EXPORT_VIEW_PROPERTY(textFieldPlaceholder, NSString *)

- (UIView *)view {
    InputTextFieldView *view = [InputTextFieldView view];
    view.textField.delegate = self;
    return view;
}

RCT_EXPORT_METHOD(sentMessage:(NSString *)message) {
    NSLog(@"JS sent message %@", message);
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:    (NSRange)range replacementString:(NSString *)string {
    NSLog(@"Entered characters: %@", string);
    InputTextFieldView *view = (id)textField.superview;
    view.shouldChangeCharacters(@{@"replacementString" : string});
    return YES;
}

@end

InputTextField.h

@interface InputTextFieldView: UIView

@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UITextField *textField;

@property (weak, nonatomic) NSString *titleLabelText;
@property (weak, nonatomic) NSString *textFieldPlaceholder;

@property (nonatomic, copy) RCTBubblingEventBlock shouldChangeCharacters;

+ (instancetype)view;

@end

InputTextFieldView.m

@interface InputTextFieldView ()

@end

@implementation InputTextFieldView

+ (instancetype)view {
    NSBundle *bundle = [NSBundle bundleForClass:[self class]];
    InputTextFieldView *view = [[bundle loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil] firstObject];
    return view;
}

- (void)setTextFieldPlaceholder:(NSString *)textFieldPlaceholder {
    self.textField.placeholder = textFieldPlaceholder;
}

- (void)setTitleLabelText:(NSString *)titleLabelText {
    self.titleLabel.text = titleLabelText;
}

@end

元素的Js代码

import React from 'react';

import { requireNativeComponent } from 'react-native';

class InputTextField extends React.Component {

  constructor() {
                super();
                console.log("start");
    this._shouldChangeCharacters = this._shouldChangeCharacters.bind(this);
  }
  _shouldChangeCharacters(event: Event) {

    console.log("InputTextField. _shouldChangeCharacters was called");

    if (!this.props.myShouldChangeCharacters) {

      return;

    }
    this.props.myShouldChangeCharacters("TEST!");
  }


  render() {
    console.log("InputTextField.render: ", InputTextFieldView)
    return <InputTextFieldView {...this.props} shouldChangeCharacters={this._shouldChangeCharacters} />;
  }
}

InputTextField.propTypes = {

  myShouldChangeCharacters: React.PropTypes.func,
  shouldChangeCharacters: React.PropTypes.func,

  titleLabelText: React.PropTypes.string,
  textFieldPlaceholder: React.PropTypes.string
};
var InputTextFieldView = requireNativeComponent('InputTextField', InputTextField);
module.exports = InputTextField;

1 个答案:

答案 0 :(得分:1)

(对于我的一个应用程序,事件名称为&#34; commandCenterEvent&#34 ;,将eventBody从NSDictionary文字转换为Javascript对象)

来自ObjC Side(您的模块):

        [_bridge.eventDispatcher sendDeviceEventWithName:@"commandCenterEvent" body:@{
            @"eventType" : @"play"
        }];

在JS方面:

const RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');

// ... in your class somewhere

    RCTDeviceEventEmitter.addListener(
        'commandCenterEvent',
        (eventObject) => {
            var eventType = eventObject.eventType;

            if (eventType == 'fileLoad') {
                this.eventObject = eventObject;

                this.emit('fileLoaded', eventObject);
            }
            else if (eventType == 'play' || eventType == 'playSleep') {
                this.emitPlay();
            }
            else if (eventType == 'pause' || eventType == 'pauseSleep') {
                this.emitPause();
            }
        }
    );