Files
react-native/React/Fabric/Mounting/ComponentViews/InputAccessory/RCTInputAccessoryComponentView.mm
T
David Vacca 3093010ea5 move fabric to ReactCommon/react/renderer
Summary:
This diff moves fabric C++ code from ReactCommon/fabric to ReactCommon/react/renderer
As part of this diff I also refactored components, codegen and callsites on CatalystApp, FB4A and venice

Script: P137350694

changelog: [internal] internal refactor

Reviewed By: fkgozali

Differential Revision: D22852139

fbshipit-source-id: f85310ba858b6afd81abfd9cbe6d70b28eca7415
2020-07-31 13:34:29 -07:00

154 lines
4.6 KiB
Plaintext

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import "RCTInputAccessoryComponentView.h"
#import <React/RCTBackedTextInputViewProtocol.h>
#import <React/RCTConversions.h>
#import <React/RCTSurfaceTouchHandler.h>
#import <React/UIView+React.h>
#import <react/renderer/components/inputaccessory/InputAccessoryComponentDescriptor.h>
#import <react/renderer/components/rncore/Props.h>
#import "RCTInputAccessoryContentView.h"
#import "RCTFabricComponentsPlugins.h"
using namespace facebook::react;
static UIView<RCTBackedTextInputViewProtocol> *_Nullable RCTFindTextInputWithNativeId(UIView *view, NSString *nativeId)
{
if ([view respondsToSelector:@selector(inputAccessoryViewID)] &&
[view respondsToSelector:@selector(setInputAccessoryView:)]) {
UIView<RCTBackedTextInputViewProtocol> *typed = (UIView<RCTBackedTextInputViewProtocol> *)view;
if (!nativeId || [typed.inputAccessoryViewID isEqualToString:nativeId]) {
return typed;
}
}
for (UIView *subview in view.subviews) {
UIView<RCTBackedTextInputViewProtocol> *result = RCTFindTextInputWithNativeId(subview, nativeId);
if (result) {
return result;
}
}
return nil;
}
@implementation RCTInputAccessoryComponentView {
InputAccessoryShadowNode::ConcreteState::Shared _state;
RCTInputAccessoryContentView *_contentView;
RCTSurfaceTouchHandler *_touchHandler;
UIView<RCTBackedTextInputViewProtocol> __weak *_textInput;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
static const auto defaultProps = std::make_shared<const InputAccessoryProps>();
_props = defaultProps;
_contentView = [RCTInputAccessoryContentView new];
_touchHandler = [RCTSurfaceTouchHandler new];
[_touchHandler attachToView:_contentView];
}
return self;
}
- (void)didMoveToWindow
{
[super didMoveToWindow];
if (self.window && !_textInput) {
if (self.nativeId) {
_textInput = RCTFindTextInputWithNativeId(self.window, self.nativeId);
_textInput.inputAccessoryView = _contentView;
} else {
_textInput = RCTFindTextInputWithNativeId(_contentView, nil);
}
if (!self.nativeId) {
[self becomeFirstResponder];
}
}
}
- (BOOL)canBecomeFirstResponder
{
return true;
}
- (UIView *)inputAccessoryView
{
return _contentView;
}
#pragma mark - RCTComponentViewProtocol
+ (ComponentDescriptorProvider)componentDescriptorProvider
{
return concreteComponentDescriptorProvider<InputAccessoryComponentDescriptor>();
}
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[_contentView insertSubview:childComponentView atIndex:index];
}
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[childComponentView removeFromSuperview];
}
- (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &)oldProps
{
auto const &oldInputAccessoryProps = *std::static_pointer_cast<InputAccessoryProps const>(_props);
auto const &newInputAccessoryProps = *std::static_pointer_cast<InputAccessoryProps const>(props);
if (newInputAccessoryProps.backgroundColor != oldInputAccessoryProps.backgroundColor) {
_contentView.backgroundColor = RCTUIColorFromSharedColor(newInputAccessoryProps.backgroundColor);
}
[super updateProps:props oldProps:oldProps];
self.hidden = true;
}
- (void)updateState:(const facebook::react::State::Shared &)state
oldState:(const facebook::react::State::Shared &)oldState
{
_state = std::static_pointer_cast<InputAccessoryShadowNode::ConcreteState const>(state);
CGSize oldScreenSize = RCTCGSizeFromSize(_state->getData().screenSize);
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
screenSize.height = std::nan("");
if (oldScreenSize.width != screenSize.width) {
auto stateData = InputAccessoryState{RCTSizeFromCGSize(screenSize)};
_state->updateState(std::move(stateData));
}
}
- (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics
{
[super updateLayoutMetrics:layoutMetrics oldLayoutMetrics:oldLayoutMetrics];
[_contentView setFrame:RCTCGRectFromRect(layoutMetrics.getContentFrame())];
}
- (void)prepareForRecycle
{
[super prepareForRecycle];
_state.reset();
_textInput = nil;
}
@end
Class<RCTComponentViewProtocol> RCTInputAccessoryCls(void)
{
return RCTInputAccessoryComponentView.class;
}