Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why is my React Native bridged component not working? #2948

Closed
chefnobody opened this Issue Sep 22, 2015 · 12 comments

Comments

Projects
None yet
6 participants
@chefnobody
Copy link

chefnobody commented Sep 22, 2015

I want to create a simple UIView subclass and then make it available as a React Native JavaScript component via bridging to React Native. I have followed these directions and thumbed through lots of the react source code: https://facebook.github.io/react-native/docs/native-components-ios.html

Unfortunately, I don't know where my React Native component is failing. This is my Obj-C manager 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

Here is my simple UIView subclass that I vend via the above -view method:

// 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

Finally, here's my react component being bridged over to JavaScript:

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

And it's declaration and render to the screen:

'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);

This results in nothing rendering to the screen when I expect to see a 100x100 red square. What I have tried:

  • I've added some border color and width to the ColorPicker to ensure that it is rendering something. It has a zero height/width, but I specify a 100x100 sized frame when I create the view.
  • I've verified that my UIView will render exactly what I expect if I remove all React Native code from the project and by putting this view as a subview of a different rootViewController.
  • I have stepped through the debugger in both Xcode and Chrome to verify that the component's manager class initializes and vends the view. (This happens twice, by the way, probably because of reloading, but that still seems inefficient).
  • I have stepped through all the bridging code as well to ensure that my module has been registered and vends its view to the list of bridged modules.
  • I have verified that ColorPicker in my main .js file is not undefined at the time its rendered to screen and when its created via debugger.
  • I have tried applying a style of height: 100, width: 100 to the rendered ColorPicker but it still doesn't show a red squARE

Questions for RN Gurus

  • What else can I do to verify that my view is correctly bridged?
  • Is there anything I should look for in the Chrome Debugger when inspecting these instances to verify that the view was set up correctly?
  • I've tried following some of the source code in the repo but I'm still new to React and I'm not 100% how its all working.
  • When I create a bridged component am I expected to set the appearance and layout in the Obj-C/Swift class or is it better to do that in JavaScript with CSS. Seems to me the former would be expected.

Any help/advice will be greatly appreciated.

@chefnobody

This comment has been minimized.

Copy link
Author

chefnobody commented Sep 28, 2015

Apparently whatever UIView instance is vended by the -view method of the "manager" class React Native mucks with its background and frame. I was able to solve this by wrapping my small 100x100 UIView in another view altogether. This is not obvious at all.

@idibidiart

This comment has been minimized.

Copy link

idibidiart commented Oct 18, 2015

Ran into the same glitch.

@browniefed

This comment has been minimized.

Copy link
Contributor

browniefed commented Mar 20, 2016

@facebook-github-bot

This comment has been minimized.

Copy link

facebook-github-bot commented Mar 20, 2016

Closing this issue as @browniefed says the question asked has been answered. Please help us by asking questions on StackOverflow. StackOverflow is amazing for Q&A: it has a reputation system, voting, the ability to mark a question as answered. Because of the reputation system it is likely the community will see and answer your question there. This also helps us use the GitHub bug tracker for bugs only.

@browniefed

This comment has been minimized.

Copy link
Contributor

browniefed commented Mar 20, 2016

If you could submit a PR to improve the documentation so that others would not run into this same issue that would be fantastic.

@chefnobody

This comment has been minimized.

Copy link
Author

chefnobody commented Mar 21, 2016

@browniefed my solution is ~6 months old. Do you think it is still viable? Also, I'm not certain where I would submit the PR or what it should look like. Comments on the manager class? Comments in the documentation?

@browniefed

This comment has been minimized.

Copy link
Contributor

browniefed commented Mar 21, 2016

@chefnobody If it applies probably just a small mention in the http://facebook.github.io/react-native/docs/native-components-ios.html#content docs. However it's up to you if you feel like the info is valuable :), no worries if you don't.

@chefnobody

This comment has been minimized.

Copy link
Author

chefnobody commented Apr 3, 2016

@browniefed #6786. Thoughts?

@ramakrishna013

This comment has been minimized.

Copy link

ramakrishna013 commented Sep 24, 2016

@chefnobody can u explain me clearly. I can't understand clearly how could you use the -view method.

@ghost

This comment has been minimized.

Copy link

ghost commented Nov 8, 2016

@chefnobody How did you wrap your square in another UIView exactly?
Did you add it as a subview?

@chefnobody

This comment has been minimized.

Copy link
Author

chefnobody commented Nov 8, 2016

Instead of returning my red square UIView in the -view method, I added that red square UIView as a subview to another UIView instance, let's call it parent. Then I returned parent from the -view method. Does that make more sense?

@ghost

This comment has been minimized.

Copy link

ghost commented Nov 10, 2016

Just as I said.
Many Thanks Aaron @chefnobody .

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.