Refactor RCTInputAccessoryView view hierarchy and names
Reviewed By: shergin Differential Revision: D7196162 fbshipit-source-id: 07a5c13d4cdb876f5a632d7d53859eab5e235f49
This commit is contained in:
parent
aa323d4aa9
commit
c136c54ff0
|
@ -419,7 +419,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
|
|||
UIView *accessoryView = [strongSelf->_bridge.uiManager viewForNativeID:nativeID
|
||||
withRootTag:rootView.reactTag];
|
||||
if (accessoryView && [accessoryView isKindOfClass:[RCTInputAccessoryView class]]) {
|
||||
strongSelf.backedTextInputView.inputAccessoryView = ((RCTInputAccessoryView *)accessoryView).content.inputAccessoryView;
|
||||
strongSelf.backedTextInputView.inputAccessoryView = ((RCTInputAccessoryView *)accessoryView).inputAccessoryView;
|
||||
[strongSelf reloadInputViewsIfNecessary];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,4 @@
|
|||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
||||
|
||||
@property (nonatomic, readonly, strong) RCTInputAccessoryViewContent *content;
|
||||
|
||||
@end
|
||||
|
|
|
@ -13,56 +13,66 @@
|
|||
|
||||
#import "RCTInputAccessoryViewContent.h"
|
||||
|
||||
@interface RCTInputAccessoryView()
|
||||
|
||||
// Overriding `inputAccessoryView` to `readwrite`.
|
||||
@property (nonatomic, readwrite, retain) UIView *inputAccessoryView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTInputAccessoryView
|
||||
{
|
||||
BOOL _contentShouldBeFirstResponder;
|
||||
BOOL _shouldBecomeFirstResponder;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
{
|
||||
if (self = [super init]) {
|
||||
_content = [RCTInputAccessoryViewContent new];
|
||||
_inputAccessoryView = [RCTInputAccessoryViewContent new];
|
||||
RCTTouchHandler *const touchHandler = [[RCTTouchHandler alloc] initWithBridge:bridge];
|
||||
[touchHandler attachToView:_content.inputAccessoryView];
|
||||
[self addSubview:_content];
|
||||
[touchHandler attachToView:_inputAccessoryView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeFirstResponder
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
- (void)reactSetFrame:(CGRect)frame
|
||||
{
|
||||
[_content.inputAccessoryView setFrame:frame];
|
||||
[_content.contentView setFrame:frame];
|
||||
[_inputAccessoryView setFrame:frame];
|
||||
|
||||
if (_contentShouldBeFirstResponder) {
|
||||
_contentShouldBeFirstResponder = NO;
|
||||
[_content becomeFirstResponder];
|
||||
if (_shouldBecomeFirstResponder) {
|
||||
_shouldBecomeFirstResponder = NO;
|
||||
[self becomeFirstResponder];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)index
|
||||
{
|
||||
[super insertReactSubview:subview atIndex:index];
|
||||
[_content insertReactSubview:subview atIndex:index];
|
||||
[_inputAccessoryView insertReactSubview:subview atIndex:index];
|
||||
}
|
||||
|
||||
- (void)removeReactSubview:(UIView *)subview
|
||||
{
|
||||
[super removeReactSubview:subview];
|
||||
[_content removeReactSubview:subview];
|
||||
[_inputAccessoryView removeReactSubview:subview];
|
||||
}
|
||||
|
||||
- (void)didUpdateReactSubviews
|
||||
{
|
||||
// Do nothing, as subviews are managed by `insertReactSubview:atIndex:`
|
||||
// Do nothing, as subviews are managed by `insertReactSubview:atIndex:`.
|
||||
}
|
||||
|
||||
- (void)didSetProps:(NSArray<NSString *> *)changedProps
|
||||
{
|
||||
// If the accessory view is not linked to a text input via nativeID, assume it is
|
||||
// a standalone component that should get focus whenever it is rendered
|
||||
// a standalone component that should get focus whenever it is rendered.
|
||||
if (![changedProps containsObject:@"nativeID"] && !self.nativeID) {
|
||||
_contentShouldBeFirstResponder = YES;
|
||||
_shouldBecomeFirstResponder = YES;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,4 @@
|
|||
|
||||
@interface RCTInputAccessoryViewContent : UIView
|
||||
|
||||
@property (nonatomic, readwrite, retain) UIView *contentView;
|
||||
|
||||
@end
|
||||
|
|
|
@ -9,65 +9,59 @@
|
|||
|
||||
#import <React/UIView+React.h>
|
||||
|
||||
@interface RCTInputAccessoryViewContent()
|
||||
|
||||
// Overriding `inputAccessoryView` to `readwrite`.
|
||||
@property (nonatomic, readwrite, retain) UIView *inputAccessoryView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTInputAccessoryViewContent
|
||||
|
||||
- (BOOL)canBecomeFirstResponder
|
||||
{
|
||||
return true;
|
||||
UIView *_safeAreaContainer;
|
||||
}
|
||||
|
||||
- (BOOL)becomeFirstResponder
|
||||
- (instancetype)init
|
||||
{
|
||||
const BOOL becameFirstResponder = [super becomeFirstResponder];
|
||||
if (self = [super init]) {
|
||||
_safeAreaContainer = [UIView new];
|
||||
[self addSubview:_safeAreaContainer];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
// Avoiding the home pill and notch (landscape mode) on iphoneX.
|
||||
if (becameFirstResponder) {
|
||||
if (@available(iOS 11.0, *)) {
|
||||
[_contentView.bottomAnchor
|
||||
constraintLessThanOrEqualToSystemSpacingBelowAnchor:_contentView.window.safeAreaLayoutGuide.bottomAnchor
|
||||
- (void)didMoveToSuperview
|
||||
{
|
||||
|
||||
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
|
||||
// Avoid the home pill (in portrait mode) and notch (in landscape mode) on iPhoneX.
|
||||
if (@available(iOS 11.0, *)) {
|
||||
if (self.window) {
|
||||
[_safeAreaContainer.bottomAnchor
|
||||
constraintLessThanOrEqualToSystemSpacingBelowAnchor:self.window.safeAreaLayoutGuide.bottomAnchor
|
||||
multiplier:1.0f].active = YES;
|
||||
[_contentView.leftAnchor
|
||||
constraintLessThanOrEqualToSystemSpacingAfterAnchor:_contentView.window.safeAreaLayoutGuide.leftAnchor
|
||||
[_safeAreaContainer.leftAnchor
|
||||
constraintGreaterThanOrEqualToSystemSpacingAfterAnchor:self.window.safeAreaLayoutGuide.leftAnchor
|
||||
multiplier:1.0f].active = YES;
|
||||
[_contentView.rightAnchor
|
||||
constraintLessThanOrEqualToSystemSpacingAfterAnchor:_contentView.window.safeAreaLayoutGuide.rightAnchor
|
||||
[_safeAreaContainer.rightAnchor
|
||||
constraintLessThanOrEqualToSystemSpacingAfterAnchor:self.window.safeAreaLayoutGuide.rightAnchor
|
||||
multiplier:1.0f].active = YES;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return becameFirstResponder;
|
||||
}
|
||||
|
||||
- (UIView *)inputAccessoryView
|
||||
- (void)setFrame:(CGRect)frame
|
||||
{
|
||||
if (!_inputAccessoryView) {
|
||||
_inputAccessoryView = [UIView new];
|
||||
_contentView = [UIView new];
|
||||
[_inputAccessoryView addSubview:_contentView];
|
||||
}
|
||||
return _inputAccessoryView;
|
||||
[super setFrame:frame];
|
||||
[_safeAreaContainer setFrame:frame];
|
||||
}
|
||||
|
||||
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)index
|
||||
{
|
||||
[super insertReactSubview:subview atIndex:index];
|
||||
[_contentView insertSubview:subview atIndex:index];
|
||||
[_safeAreaContainer insertSubview:subview atIndex:index];
|
||||
}
|
||||
|
||||
- (void)removeReactSubview:(UIView *)subview
|
||||
{
|
||||
[super removeReactSubview:subview];
|
||||
[subview removeFromSuperview];
|
||||
if ([[_inputAccessoryView subviews] count] == 0 && [self isFirstResponder]) {
|
||||
if ([[_safeAreaContainer subviews] count] == 0 && [self isFirstResponder]) {
|
||||
[self resignFirstResponder];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,6 @@ RCT_EXPORT_MODULE()
|
|||
return [[RCTInputAccessoryView alloc] initWithBridge:self.bridge];
|
||||
}
|
||||
|
||||
RCT_REMAP_VIEW_PROPERTY(backgroundColor, content.inputAccessoryView.backgroundColor, UIColor)
|
||||
RCT_REMAP_VIEW_PROPERTY(backgroundColor, inputAccessoryView.backgroundColor, UIColor)
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue