I am making a simple "check box" native component for React Native. It is for macOS, but it has made similar way as iOS.
This is my code:
RNCCheckBox.m:
#import <AppKit/AppKit.h>
@interface RNCCheckBox : NSView
@property (nonatomic, copy) NSString *title;
@property (nonatomic, assign) BOOL isSelected;
@end
@implementation RNCCheckBox
- (instancetype)init
{
self = [super initWithFrame:NSMakeRect(50, -100, 50, -100)]; // weird value, but this works, positive values does not.
if (self) {
_title = @"";
_isSelected = YES; // or NO
NSButton *cb = [[NSButton alloc] initWithFrame:self.frame];
[cb setTitle:_title];
[cb setButtonType:NSButtonTypeSwitch];
[cb setTarget:self];
[cb setState:_isSelected];
[cb setAction:@selector(clicked:)];
[self addSubview:cb];
// [cb performClick:self]; this works, but mouse click does not.
}
return self;
}
- (void)setTitle:(NSString *)title
{
if (![_title isEqual:title])
_title = [title copy];
}
- (void)setIsSelected:(BOOL)isSelected
{
if (_isSelected != isSelected)
_isSelected = isSelected;
}
- (void)clicked:(id)sender // does not invokes
{
NSButton *cb = (NSButton *)sender;
[cb setState:_isSelected];
}
@end
RNCCheckBoxManager.m:
#import <React/RCTViewManager.h>
#import "RNCCheckBox.h"
@interface RNCCheckBoxManager : RCTViewManager
@end
@implementation RNCCheckBoxManager
RCT_EXPORT_MODULE()
- (NSView *)view
{
NSView *view = [RNCCheckBox new];
return view;
}
RCT_EXPORT_VIEW_PROPERTY(title, NSString *)
RCT_EXPORT_VIEW_PROPERTY(isSelected, BOOL)
@end
CheckBox.tsx:
import React from 'react';
import { requireNativeComponent } from "react-native";
const RNCCheckBox = requireNativeComponent('RNCCheckBox');
export class CheckBox extends React.Component<{ title: string, isSelected: boolean }> {
render() {
return (
<RNCCheckBox { ...this.props } /> // props does not injected
);
}
}
module.exports = CheckBox;
App.tsx in my app:
import React from 'react';
import { View } from 'react-native';
import { CheckBox } from 'react-native-my-checkbox';
export default class App extends React.Component<undefined, { checked: boolean }> {
constructor(props: undefined) {
super(props);
this.state = { checked: false };
}
render() {
return (
<View>
<CheckBox title={'Test'} isSelected={ this.state.checked } />
</View>
);
}
}
These code doesn't work properly - check box appears, but not clickable, and props are not injected.
Also its position doesn't follow its <View />
, so I have to set it manually by initWithFrame
.
If I change to init
, only blue dot shows on upper left corner.
Where am I doing wrong?