为什么我的 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 的红色方块时,这导致屏幕上没有任何渲染。我尝试过的:
- 我已将一些边框颜色和宽度添加到 ColorPicker 以确保它正在渲染某些内容。它有一个零 height/width,但我在创建视图时指定了一个 100x100 大小的框架。
- 我已经验证,如果我从项目中删除所有 React Native 代码并将此视图作为另一个
rootViewController
的子视图,我的 UIView
将呈现我期望的效果。 =50=]
- 我已经在 Xcode 和 Chrome 中单步执行了调试器,以验证组件的管理器 class 是否初始化并提供了视图。 (顺便说一句,这可能是因为重新加载,但仍然效率低下。
- 我也已逐步完成所有桥接代码,以确保我的模块已注册并将其视图提供给桥接模块列表。
- 我已经确认我的主 .js 文件中的
ColorPicker
在渲染到屏幕时和通过 debugger
创建时不是 undefined
。
- 我已经尝试将
height: 100, width: 100
的样式应用到呈现的 ColorPicker
但它仍然没有显示红色正方形
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 个(或更多)实例。
我想创建一个简单的 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 的红色方块时,这导致屏幕上没有任何渲染。我尝试过的:
- 我已将一些边框颜色和宽度添加到 ColorPicker 以确保它正在渲染某些内容。它有一个零 height/width,但我在创建视图时指定了一个 100x100 大小的框架。
- 我已经验证,如果我从项目中删除所有 React Native 代码并将此视图作为另一个
rootViewController
的子视图,我的UIView
将呈现我期望的效果。 =50=] - 我已经在 Xcode 和 Chrome 中单步执行了调试器,以验证组件的管理器 class 是否初始化并提供了视图。 (顺便说一句,这可能是因为重新加载,但仍然效率低下。
- 我也已逐步完成所有桥接代码,以确保我的模块已注册并将其视图提供给桥接模块列表。
- 我已经确认我的主 .js 文件中的
ColorPicker
在渲染到屏幕时和通过debugger
创建时不是undefined
。 - 我已经尝试将
height: 100, width: 100
的样式应用到呈现的ColorPicker
但它仍然没有显示红色正方形
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 个(或更多)实例。