Skip to content

Commit

Permalink
add RNTester example for native command Array param (#41897)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #41897

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D51875073

fbshipit-source-id: 403274b3063d7c49fe4642347d2f724d58a46c1f
  • Loading branch information
zeyap authored and facebook-github-bot committed Dec 15, 2023
1 parent 8e1c45a commit 5d1eac0
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#import <React/RCTViewManager.h>
#import "RNTLegacyView.h"
#import "RNTMyNativeViewComponentView.h"
#import "UIView+ColorOverlays.h"

@interface RNTMyLegacyNativeViewManager : RCTViewManager

Expand Down Expand Up @@ -40,27 +41,40 @@ + (BOOL)requiresMainQueueSetup
RCT_EXPORT_METHOD(changeBackgroundColor : (nonnull NSNumber *)reactTag color : (NSString *)color)
{
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
UIView *view = viewRegistry[reactTag];
if (!view || ![view isKindOfClass:[RNTLegacyView class]]) {
RCTLogError(@"Cannot find RNTLegacyView with tag #%@", reactTag);
return;
if (UIView *view = [RNTMyLegacyNativeViewManager getViewByTag:viewRegistry reactTag:reactTag]) {
[view setBackgroundColorWithColorString:color];
}
}];
}

unsigned rgbValue = 0;
NSString *colorString = [NSString stringWithCString:std::string([color UTF8String]).c_str()
encoding:[NSString defaultCStringEncoding]];
NSScanner *scanner = [NSScanner scannerWithString:colorString];
[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&rgbValue];

UIColor *newColor = [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0
green:((rgbValue & 0xFF00) >> 8) / 255.0
blue:(rgbValue & 0xFF) / 255.0
alpha:1.0];
view.backgroundColor = newColor;
RCT_EXPORT_METHOD(addOverlays : (nonnull NSNumber *)reactTag overlayColors : (NSArray *)overlayColors)
{
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
if (UIView *view = [RNTMyLegacyNativeViewManager getViewByTag:viewRegistry reactTag:reactTag]) {
[view addColorOverlays:overlayColors];
}
}];
}

RCT_EXPORT_METHOD(removeOverlays : (nonnull NSNumber *)reactTag)
{
[self.bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry) {
if (UIView *view = [RNTMyLegacyNativeViewManager getViewByTag:viewRegistry reactTag:reactTag]) {
[view removeOverlays];
}
}];
}

+ (UIView *)getViewByTag:(NSDictionary<NSNumber *, UIView *> *)viewRegistry reactTag:(nonnull NSNumber *)reactTag
{
UIView *view = viewRegistry[reactTag];
if (!view || ![view isKindOfClass:[RNTLegacyView class]]) {
RCTLogError(@"Cannot find RNTLegacyView with tag #%@", reactTag);
return NULL;
}
return view;
}

- (UIView *)view
{
RNTLegacyView *view = [[RNTLegacyView alloc] init];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import "UIView+ColorOverlays.h"

@implementation UIView (ColorOverlays)

- (void)setBackgroundColorWithColorString:(NSString *)colorString
{
UIColor *color = [UIView UIColorFromHexString:std::string([colorString UTF8String])];
self.backgroundColor = color;
}

- (void)addColorOverlays:(const NSArray *)overlayColors
{
CGRect viewBounds = self.bounds;
CGFloat width = viewBounds.size.width / [overlayColors count];
for (int i = 0; i < [overlayColors count]; i++) {
id colorString = [overlayColors objectAtIndex:i];
CGRect rect = CGRectMake(viewBounds.origin.x + width * i, viewBounds.origin.y, width, viewBounds.size.height);
UIView *overlayView = [[UIView alloc] initWithFrame:rect];
UIColor *color = [UIView UIColorFromHexString:std::string([colorString UTF8String])];
overlayView.backgroundColor = color;
[self addSubview:overlayView];
}
}

- (void)removeOverlays
{
NSArray *viewsToRemove = [self subviews];
for (UIView *subview in viewsToRemove) {
[subview removeFromSuperview];
}
}

+ (UIColor *)UIColorFromHexString:(const std::string)hexString
{
unsigned rgbValue = 0;
NSString *colorString = [NSString stringWithCString:hexString.c_str() encoding:[NSString defaultCStringEncoding]];
NSScanner *scanner = [NSScanner scannerWithString:colorString];
[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&rgbValue];
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0
green:((rgbValue & 0xFF00) >> 8) / 255.0
blue:(rgbValue & 0xFF) / 255.0
alpha:1.0];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ NS_ASSUME_NONNULL_BEGIN

@property (nonatomic, copy) RCTBubblingEventBlock onIntArrayChanged;

- (UIColor *)UIColorFromHexString:(const std::string)hexString;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#import "RNTMyNativeViewComponentView.h"
#import "UIView+ColorOverlays.h"

#import <react/renderer/components/AppSpecs/ComponentDescriptors.h>
#import <react/renderer/components/AppSpecs/EventEmitters.h>
Expand Down Expand Up @@ -51,19 +52,6 @@ - (instancetype)initWithFrame:(CGRect)frame
return self;
}

- (UIColor *)UIColorFromHexString:(const std::string)hexString
{
unsigned rgbValue = 0;
NSString *colorString = [NSString stringWithCString:hexString.c_str() encoding:[NSString defaultCStringEncoding]];
NSScanner *scanner = [NSScanner scannerWithString:colorString];
[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&rgbValue];
return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0
green:((rgbValue & 0xFF00) >> 8) / 255.0
blue:(rgbValue & 0xFF) / 255.0
alpha:1.0];
}

- (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &)oldProps
{
const auto &oldViewProps = *std::static_pointer_cast<const RNTMyNativeViewProps>(_props);
Expand Down Expand Up @@ -123,9 +111,19 @@ - (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args

- (void)callNativeMethodToChangeBackgroundColor:(NSString *)colorString
{
UIColor *color = [self UIColorFromHexString:std::string([colorString UTF8String])];
_view.backgroundColor = color;
[_view setBackgroundColorWithColorString:colorString];
}

- (void)callNativeMethodToAddOverlays:(const NSArray *)overlayColors
{
[_view addColorOverlays:overlayColors];
}

- (void)callNativeMethodToRemoveOverlays
{
[_view removeOverlays];
}

@end

Class<RCTComponentViewProtocol> RNTMyNativeViewCls(void)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#import <React/RCTLog.h>
#import <React/RCTUIManager.h>
#import <React/RCTViewManager.h>
#import "UIView+ColorOverlays.h"

@interface RNTMyNativeViewManager : RCTViewManager
@end
Expand All @@ -31,17 +32,7 @@ @implementation RNTMyNativeViewManager
return;
}

unsigned rgbValue = 0;
NSString *colorString = [NSString stringWithCString:std::string([color UTF8String]).c_str()
encoding:[NSString defaultCStringEncoding]];
NSScanner *scanner = [NSScanner scannerWithString:colorString];
[scanner setScanLocation:1]; // bypass '#' character
[scanner scanHexInt:&rgbValue];

view.backgroundColor = [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16) / 255.0
green:((rgbValue & 0xFF00) >> 8) / 255.0
blue:(rgbValue & 0xFF) / 255.0
alpha:1.0];
[view setBackgroundColorWithColorString:color];
}];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#import <React/RCTComponent.h>
#import <UIKit/UIKit.h>
#import <string>

NS_ASSUME_NONNULL_BEGIN

@interface UIView (ColorOverlays)

- (void)setBackgroundColorWithColorString:(NSString *)colorString;
- (void)addColorOverlays:(const NSArray *)overlayColors;
- (void)removeOverlays;
+ (UIColor *)UIColorFromHexString:(const std::string)hexString;

@end

NS_ASSUME_NONNULL_END
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,39 @@ export function callNativeMethodToChangeBackgroundColor(
);
}

export function callNativeMethodToAddOverlays(
viewRef: React.ElementRef<MyLegacyViewType> | null,
overlayColors: $ReadOnlyArray<string>,
) {
if (!viewRef) {
console.log('viewRef is null');
return;
}
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(viewRef),
UIManager.getViewManagerConfig(
'RNTMyLegacyNativeView',
).Commands.addOverlays.toString(),
[overlayColors],
);
}

export function callNativeMethodToRemoveOverlays(
viewRef: React.ElementRef<MyLegacyViewType> | null,
) {
if (!viewRef) {
console.log('viewRef is null');
return;
}
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(viewRef),
UIManager.getViewManagerConfig(
'RNTMyLegacyNativeView',
).Commands.removeOverlays.toString(),
[],
);
}

export default (requireNativeComponent(
'RNTMyLegacyNativeView',
): HostComponent<NativeProps>);
32 changes: 31 additions & 1 deletion packages/rn-tester/NativeComponentExample/js/MyNativeView.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import type {MyLegacyViewType} from './MyLegacyViewNativeComponent';
import type {MyNativeViewType} from './MyNativeViewNativeComponent';

import RNTMyLegacyNativeView from './MyLegacyViewNativeComponent';
import {callNativeMethodToChangeBackgroundColor} from './MyLegacyViewNativeComponent';
import {
callNativeMethodToAddOverlays,
callNativeMethodToChangeBackgroundColor,
callNativeMethodToRemoveOverlays,
} from './MyLegacyViewNativeComponent';
import RNTMyNativeView, {
Commands as RNTMyNativeViewCommands,
} from './MyNativeViewNativeComponent';
Expand Down Expand Up @@ -152,6 +156,32 @@ export default function MyNativeView(props: {}): React.Node {
callNativeMethodToChangeBackgroundColor(legacyRef.current, newColor);
}}
/>
<Button
title="Add Overlays"
onPress={() => {
let randomColorId = Math.floor(Math.random() * 5);
let overlayColors = [
colors[randomColorId],
colors[(randomColorId + 1) % 5],
];
RNTMyNativeViewCommands.callNativeMethodToAddOverlays(
// $FlowFixMe[incompatible-call]
ref.current,
overlayColors,
);
callNativeMethodToAddOverlays(legacyRef.current, overlayColors);
}}
/>
<Button
title="Remove Overlays"
onPress={() => {
RNTMyNativeViewCommands.callNativeMethodToRemoveOverlays(
// $FlowFixMe[incompatible-call]
ref.current,
);
callNativeMethodToRemoveOverlays(legacyRef.current);
}}
/>
<Button
title="Set Opacity"
onPress={() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,23 @@ interface NativeCommands {
viewRef: React.ElementRef<MyNativeViewType>,
color: string,
) => void;

+callNativeMethodToAddOverlays: (
viewRef: React.ElementRef<MyNativeViewType>,
overlayColors: $ReadOnlyArray<string>,
) => void;

+callNativeMethodToRemoveOverlays: (
viewRef: React.ElementRef<MyNativeViewType>,
) => void;
}

export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
supportedCommands: ['callNativeMethodToChangeBackgroundColor'],
supportedCommands: [
'callNativeMethodToChangeBackgroundColor',
'callNativeMethodToAddOverlays',
'callNativeMethodToRemoveOverlays',
],
});

export default (codegenNativeComponent<NativeProps>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,26 @@ internal class MyLegacyViewManager(reactContext: ReactApplicationContext) :
val sentColor: Int = Color.parseColor(args?.getString(0))
view.setBackgroundColor(sentColor)
}
COMMAND_ADD_OVERLAYS -> {
val overlayColors: ReadableArray = args!!.getArray(0)
view.addOverlays(overlayColors)
}
COMMAND_REMOVE_OVERLAYS -> {
view.removeOverlays()
}
}
}

override fun getCommandsMap(): Map<String, Int> =
mapOf("changeBackgroundColor" to COMMAND_CHANGE_BACKGROUND_COLOR)
mapOf(
"changeBackgroundColor" to COMMAND_CHANGE_BACKGROUND_COLOR,
"addOverlays" to COMMAND_ADD_OVERLAYS,
"removeOverlays" to COMMAND_REMOVE_OVERLAYS)

companion object {
const val REACT_CLASS = "RNTMyLegacyNativeView"
const val COMMAND_CHANGE_BACKGROUND_COLOR = 42
const val COMMAND_CHANGE_BACKGROUND_COLOR = 1
const val COMMAND_ADD_OVERLAYS = 2
const val COMMAND_REMOVE_OVERLAYS = 3
}
}

0 comments on commit 5d1eac0

Please sign in to comment.