为什么我的 React Native 桥接 iOS 组件不起作用?

Why does my React Native bridged iOS component not work?

我想创建一个简单的 UIView subclass,然后通过桥接到 React Native 使其作为 React Native JavaScript 组件可用。我遵循了这些指示并浏览了很多反应源代码:https://facebook.github.io/react-native/docs/native-components-ios.html

不幸的是,我不知道我的 React Native 组件哪里出了问题。这是我的 Obj-C 管理器 class:

// header
#import "RCTViewManager.h"
#import "ColorPicker.h"

@interface ColorPickerManager : RCTViewManager

@end

// implementation
#import "ColorPickerManager.h"

@interface ColorPickerManager()

@property (nonatomic) ColorPicker * colorPicker;

@end

@implementation ColorPickerManager

RCT_EXPORT_MODULE()

- (instancetype)init {
    self = [super init];
    if ( self ) {
        NSLog(@"color picker manager init");
    self.colorPicker = [[ColorPicker alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    }
    return self;
}

- (UIView *)view {
    NSLog(@"color picker manager -view method");
    return self.colorPicker;
}

@end

这是我通过上述 -view 方法提供的简单 UIView subclass:

// header
#import <UIKit/UIKit.h>

@interface ColorPicker : UIView

@end

// implementation
#import "ColorPicker.h"

@interface ColorPicker()

@property (nonatomic) NSArray * colors;

@end

@implementation ColorPicker

- (instancetype)init {
    NSLog(@"init");
    self = [super init];
    if ( self ) {
       [self setUp];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    NSLog(@"init with frame: %@", NSStringFromCGRect(frame));
    self = [super initWithFrame:frame];
    if ( self ) {
        [self setUp];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    NSLog(@"init with coder: %@", aDecoder);
   self = [super initWithCoder:aDecoder];
   if ( self ) {
       [self setUp];
   }
   return self;
}

- (void)setUp {
    self.colors = @[[UIColor redColor], [UIColor greenColor], [UIColor blueColor]];
    self.backgroundColor = self.colors[0];
}

- (void)layoutSubviews {
    NSLog(@"layout subviews");
}

@end

最后,这是我的反应组件被桥接到 JavaScript:

var { requireNativeComponent } = require('react-native');
var ColorPicker = requireNativeComponent('ColorPicker', null);
module.exports = ColorPicker;
debugger;

它的声明和渲染到屏幕:

'use strict';
var React = require('react-native');
var ColorPicker = require('./BridgedComponents/ColorPicker.js');


var {
  StyleSheet
} = React;

var iOS = React.createClass({

    render: function() {
        debugger;
        return (
            <ColorPicker style={styles.container} />
        );
    }
});

var styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
});

AppRegistry.registerComponent('iOS', () => iOS);

当我希望看到一个 100x100 的红色方块时,这导致屏幕上没有任何渲染。我尝试过的:

RN 大师的问题 - 我还能做些什么来验证我的视图是否正确桥接? - 在检查这些实例以验证视图设置是否正确时,我应该在 Chrome 调试器中寻找什么? - 我已经尝试遵循 repo 中的一些源代码,但我仍然是 React 的新手,我不是 100% 了解它是如何工作的。 - 当我创建桥接组件时,我希望在 Obj-C/Swift class 中设置外观和布局,还是在 JavaScript 和 CSS 中设置外观和布局更好?在我看来是前者。

任何 help/advice 将不胜感激。

除了您的 ColorPicker 视图外,您什么也看不到。

问题是 ReactNative 正在管理其 backgroundColor 属性 本身并覆盖您的初始选择。

您可以在您的 ColorPicker.m 中添加以下方法并设置断点以查看它何时发生:

- (void)setBackgroundColor:(UIColor *)backgroundColor {
    NSLog(@"setBackgroundColor %@", backgroundColor);
    [super setBackgroundColor:backgroundColor];
}

您应该让 React Native 处理桥接组件的大小和外观。 但是完全可以找到完全由本机端控制的自定义子视图。

还有您桥接的视图的 ColorPickerManager should return a new instance 每当它调用 view 方法时。

即你应该使用这个:

@implementation ColorPickerManager

RCT_EXPORT_MODULE()

- (instancetype)init {
  self = [super init];
  if ( self ) {
    NSLog(@"color picker manager init");
  }
  return self;
}

- (UIView *)view {
  NSLog(@"color picker manager -view method");
  return [[ColorPicker alloc] init];
}

@end

否则您将无法显示 ColorPicker 组件的 2 个(或更多)实例。