RCTTextField was spliited into two classes
Summary: Motivation: * We maintain two different implementation of <TextInput> (multilined and singlelined), this change makes the implementations much similar which will help us to support and improve both of them in the (near) future; * We have to have separated RCTView-based container view for (TextField) to support sofisticated bordering and so on; * It opens to us possibility to unify UITextView and UITextField subclasses and remove code duplication across RCTTextView and RCTTextField; * Making things decoupled in general will allow us to fix existing bugs with events. Reviewed By: mmmulani Differential Revision: D5083010 fbshipit-source-id: 2f2d42c2244d2b39256c51480c1f16f4e3947c01
This commit is contained in:
parent
48650226e8
commit
e13b9c6e49
|
@ -27,6 +27,8 @@
|
|||
58B511D01A9E6C5C00147676 /* RCTShadowText.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B511CB1A9E6C5C00147676 /* RCTShadowText.m */; };
|
||||
58B511D11A9E6C5C00147676 /* RCTTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B511CD1A9E6C5C00147676 /* RCTTextManager.m */; };
|
||||
58B512161A9E6EFF00147676 /* RCTText.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B512141A9E6EFF00147676 /* RCTText.m */; };
|
||||
59AF89AA1EDCBCC700F004B1 /* RCTUITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 59AF89A91EDCBCC700F004B1 /* RCTUITextField.m */; };
|
||||
59AF89AB1EDCBCC700F004B1 /* RCTUITextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 59AF89A91EDCBCC700F004B1 /* RCTUITextField.m */; };
|
||||
59B125C91E6E4E15004E2A67 /* RCTUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59B125C81E6E4E15004E2A67 /* RCTUITextView.m */; };
|
||||
59B125CA1E6E4E15004E2A67 /* RCTUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59B125C81E6E4E15004E2A67 /* RCTUITextView.m */; };
|
||||
59F60E911E661BDD0081153B /* RCTShadowTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F60E8E1E661BDD0081153B /* RCTShadowTextField.m */; };
|
||||
|
@ -60,6 +62,8 @@
|
|||
58B511CD1A9E6C5C00147676 /* RCTTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTextManager.m; sourceTree = "<group>"; };
|
||||
58B512141A9E6EFF00147676 /* RCTText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTText.m; sourceTree = "<group>"; };
|
||||
58B512151A9E6EFF00147676 /* RCTText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTText.h; sourceTree = "<group>"; };
|
||||
59AF89A81EDCBCC700F004B1 /* RCTUITextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTUITextField.h; sourceTree = "<group>"; };
|
||||
59AF89A91EDCBCC700F004B1 /* RCTUITextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUITextField.m; sourceTree = "<group>"; };
|
||||
59B125C71E6E4E15004E2A67 /* RCTUITextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTUITextView.h; sourceTree = "<group>"; };
|
||||
59B125C81E6E4E15004E2A67 /* RCTUITextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUITextView.m; sourceTree = "<group>"; };
|
||||
59F60E8D1E661BDD0081153B /* RCTShadowTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTShadowTextField.h; sourceTree = "<group>"; };
|
||||
|
@ -101,6 +105,8 @@
|
|||
131B6ABD1AF0CD0600FFC3E0 /* RCTTextView.m */,
|
||||
131B6ABE1AF0CD0600FFC3E0 /* RCTTextViewManager.h */,
|
||||
131B6ABF1AF0CD0600FFC3E0 /* RCTTextViewManager.m */,
|
||||
59AF89A81EDCBCC700F004B1 /* RCTUITextField.h */,
|
||||
59AF89A91EDCBCC700F004B1 /* RCTUITextField.m */,
|
||||
59B125C71E6E4E15004E2A67 /* RCTUITextView.h */,
|
||||
59B125C81E6E4E15004E2A67 /* RCTUITextView.m */,
|
||||
);
|
||||
|
@ -196,6 +202,7 @@
|
|||
2D3B5F391D9B106F00451313 /* RCTTextField.m in Sources */,
|
||||
2D3B5F361D9B106F00451313 /* RCTShadowText.m in Sources */,
|
||||
2D3B5F3B1D9B106F00451313 /* RCTTextView.m in Sources */,
|
||||
59AF89AB1EDCBCC700F004B1 /* RCTUITextField.m in Sources */,
|
||||
2D3B5F3A1D9B106F00451313 /* RCTTextFieldManager.m in Sources */,
|
||||
2D3B5F341D9B103100451313 /* RCTRawTextManager.m in Sources */,
|
||||
59F60E921E661BDD0081153B /* RCTShadowTextField.m in Sources */,
|
||||
|
@ -217,6 +224,7 @@
|
|||
58B511CE1A9E6C5C00147676 /* RCTRawTextManager.m in Sources */,
|
||||
19FC5C851D41A4120090108F /* RCTTextSelection.m in Sources */,
|
||||
1362F1001B4D51F400E06D8C /* RCTTextField.m in Sources */,
|
||||
59AF89AA1EDCBCC700F004B1 /* RCTUITextField.m in Sources */,
|
||||
58B512161A9E6EFF00147676 /* RCTText.m in Sources */,
|
||||
1362F1011B4D51F400E06D8C /* RCTTextFieldManager.m in Sources */,
|
||||
59F60E911E661BDD0081153B /* RCTShadowTextField.m in Sources */,
|
||||
|
|
|
@ -10,15 +10,16 @@
|
|||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTComponent.h>
|
||||
#import <React/RCTView.h>
|
||||
|
||||
@class RCTBridge;
|
||||
@class RCTUITextField;
|
||||
|
||||
@interface RCTTextField : UITextField
|
||||
@interface RCTTextField : RCTView
|
||||
|
||||
@property (nonatomic, assign) BOOL caretHidden;
|
||||
@property (nonatomic, assign) BOOL selectTextOnFocus;
|
||||
@property (nonatomic, assign) BOOL blurOnSubmit;
|
||||
@property (nonatomic, strong) UIColor *placeholderTextColor;
|
||||
@property (nonatomic, assign) NSInteger mostRecentEventCount;
|
||||
@property (nonatomic, strong) NSNumber *maxLength;
|
||||
@property (nonatomic, assign) UIEdgeInsets reactPaddingInsets;
|
||||
|
@ -26,6 +27,11 @@
|
|||
|
||||
@property (nonatomic, copy) RCTDirectEventBlock onSelectionChange;
|
||||
|
||||
@property (nonatomic, strong) RCTUITextField *textField;
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
|
||||
|
||||
@end
|
||||
|
|
|
@ -17,33 +17,9 @@
|
|||
#import <React/UIView+React.h>
|
||||
|
||||
#import "RCTTextSelection.h"
|
||||
#import "RCTUITextField.h"
|
||||
|
||||
@interface RCTTextField()
|
||||
|
||||
- (BOOL)shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
|
||||
- (BOOL)keyboardInputShouldDelete;
|
||||
- (BOOL)textFieldShouldEndEditing;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTTextFieldDelegateProxy: NSObject <UITextFieldDelegate>
|
||||
@end
|
||||
|
||||
@implementation RCTTextFieldDelegateProxy
|
||||
|
||||
- (BOOL)textField:(RCTTextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
|
||||
{
|
||||
return [textField shouldChangeCharactersInRange:range replacementString:string];
|
||||
}
|
||||
|
||||
- (BOOL)keyboardInputShouldDelete:(RCTTextField *)textField
|
||||
{
|
||||
return [textField keyboardInputShouldDelete];
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldEndEditing:(RCTTextField *)textField {
|
||||
return [textField textFieldShouldEndEditing];
|
||||
}
|
||||
@interface RCTTextField () <UITextFieldDelegate>
|
||||
|
||||
@end
|
||||
|
||||
|
@ -54,9 +30,8 @@
|
|||
NSInteger _nativeEventCount;
|
||||
BOOL _submitted;
|
||||
UITextRange *_previousSelectionRange;
|
||||
BOOL _textWasPasted;
|
||||
NSString *_finalText;
|
||||
RCTTextFieldDelegateProxy *_delegateProxy;
|
||||
CGSize _previousContentSize;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
||||
|
@ -66,30 +41,38 @@
|
|||
|
||||
_bridge = bridge;
|
||||
_eventDispatcher = bridge.eventDispatcher;
|
||||
_blurOnSubmit = YES;
|
||||
|
||||
[self addTarget:self action:@selector(textFieldDidChange) forControlEvents:UIControlEventEditingChanged];
|
||||
[self addTarget:self action:@selector(textFieldBeginEditing) forControlEvents:UIControlEventEditingDidBegin];
|
||||
[self addTarget:self action:@selector(textFieldEndEditing) forControlEvents:UIControlEventEditingDidEnd];
|
||||
[self addTarget:self action:@selector(textFieldSubmitEditing) forControlEvents:UIControlEventEditingDidEndOnExit];
|
||||
[self addObserver:self forKeyPath:@"selectedTextRange" options:0 context:nil];
|
||||
_textField = [[RCTUITextField alloc] initWithFrame:self.bounds];
|
||||
_textField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
|
||||
// We cannot use `self.delegate = self;` here because `UITextField` implements some of these delegate methods itself,
|
||||
// so if we implement this delegate on self, we will override some of its behaviours.
|
||||
_delegateProxy = [RCTTextFieldDelegateProxy new];
|
||||
self.delegate = _delegateProxy;
|
||||
// Note: `UITextField` fires same events to channels in this order: delegate method, notification center, target action.
|
||||
// Usually (presumably) all events with equivalent semantic fires consistently in specified order...
|
||||
// but in practice, it is not always true, unfortunately.
|
||||
// Surprisingly, seems subscribing via Notification Center is the most reliable way to get these events.
|
||||
|
||||
_textField.delegate = self;
|
||||
|
||||
[_textField addTarget:self action:@selector(textFieldDidChange) forControlEvents:UIControlEventEditingChanged];
|
||||
[_textField addTarget:self action:@selector(textFieldBeginEditing) forControlEvents:UIControlEventEditingDidBegin];
|
||||
[_textField addTarget:self action:@selector(textFieldEndEditing) forControlEvents:UIControlEventEditingDidEnd];
|
||||
[_textField addTarget:self action:@selector(textFieldSubmitEditing) forControlEvents:UIControlEventEditingDidEndOnExit];
|
||||
|
||||
[_textField addObserver:self forKeyPath:@"selectedTextRange" options:0 context:nil];
|
||||
|
||||
[self addSubview:_textField];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self removeObserver:self forKeyPath:@"selectedTextRange"];
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
|
||||
RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_textField removeObserver:self forKeyPath:@"selectedTextRange"];
|
||||
}
|
||||
|
||||
- (void)sendKeyValueForString:(NSString *)string
|
||||
{
|
||||
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeKeyPress
|
||||
|
@ -99,12 +82,22 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
eventCount:_nativeEventCount];
|
||||
}
|
||||
|
||||
// This method is overridden for `onKeyPress`. The manager
|
||||
// will not send a keyPress for text that was pasted.
|
||||
- (void)paste:(id)sender
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setReactPaddingInsets:(UIEdgeInsets)reactPaddingInsets
|
||||
{
|
||||
_textWasPasted = YES;
|
||||
[super paste:sender];
|
||||
_reactPaddingInsets = reactPaddingInsets;
|
||||
// We apply `paddingInsets` as `_textField`'s `textContainerInset`.
|
||||
_textField.textContainerInset = reactPaddingInsets;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)setReactBorderInsets:(UIEdgeInsets)reactBorderInsets
|
||||
{
|
||||
_reactBorderInsets = reactBorderInsets;
|
||||
// We apply `borderInsets` as `_textView` layout offset.
|
||||
_textField.frame = UIEdgeInsetsInsetRect(self.bounds, reactBorderInsets);
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)setSelection:(RCTTextSelection *)selection
|
||||
|
@ -113,90 +106,47 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
return;
|
||||
}
|
||||
|
||||
UITextRange *currentSelection = self.selectedTextRange;
|
||||
UITextPosition *start = [self positionFromPosition:self.beginningOfDocument offset:selection.start];
|
||||
UITextPosition *end = [self positionFromPosition:self.beginningOfDocument offset:selection.end];
|
||||
UITextRange *selectedTextRange = [self textRangeFromPosition:start toPosition:end];
|
||||
UITextRange *currentSelection = _textField.selectedTextRange;
|
||||
UITextPosition *start = [_textField positionFromPosition:_textField.beginningOfDocument offset:selection.start];
|
||||
UITextPosition *end = [_textField positionFromPosition:_textField.beginningOfDocument offset:selection.end];
|
||||
UITextRange *selectedTextRange = [_textField textRangeFromPosition:start toPosition:end];
|
||||
|
||||
NSInteger eventLag = _nativeEventCount - _mostRecentEventCount;
|
||||
if (eventLag == 0 && ![currentSelection isEqual:selectedTextRange]) {
|
||||
_previousSelectionRange = selectedTextRange;
|
||||
self.selectedTextRange = selectedTextRange;
|
||||
_textField.selectedTextRange = selectedTextRange;
|
||||
} else if (eventLag > RCTTextUpdateLagWarningThreshold) {
|
||||
RCTLogWarn(@"Native TextInput(%@) is %zd events ahead of JS - try to make your JS faster.", self.text, eventLag);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)text
|
||||
{
|
||||
return _textField.text;
|
||||
}
|
||||
|
||||
- (void)setText:(NSString *)text
|
||||
{
|
||||
NSInteger eventLag = _nativeEventCount - _mostRecentEventCount;
|
||||
if (eventLag == 0 && ![text isEqualToString:self.text]) {
|
||||
UITextRange *selection = self.selectedTextRange;
|
||||
NSInteger oldTextLength = self.text.length;
|
||||
UITextRange *selection = _textField.selectedTextRange;
|
||||
NSInteger oldTextLength = _textField.text.length;
|
||||
|
||||
super.text = text;
|
||||
_textField.text = text;
|
||||
|
||||
if (selection.empty) {
|
||||
// maintain cursor position relative to the end of the old text
|
||||
NSInteger offsetStart = [self offsetFromPosition:self.beginningOfDocument toPosition:selection.start];
|
||||
NSInteger offsetStart = [_textField offsetFromPosition:_textField.beginningOfDocument toPosition:selection.start];
|
||||
NSInteger offsetFromEnd = oldTextLength - offsetStart;
|
||||
NSInteger newOffset = text.length - offsetFromEnd;
|
||||
UITextPosition *position = [self positionFromPosition:self.beginningOfDocument offset:newOffset];
|
||||
self.selectedTextRange = [self textRangeFromPosition:position toPosition:position];
|
||||
UITextPosition *position = [_textField positionFromPosition:_textField.beginningOfDocument offset:newOffset];
|
||||
_textField.selectedTextRange = [_textField textRangeFromPosition:position toPosition:position];
|
||||
}
|
||||
} else if (eventLag > RCTTextUpdateLagWarningThreshold) {
|
||||
RCTLogWarn(@"Native TextInput(%@) is %zd events ahead of JS - try to make your JS faster.", self.text, eventLag);
|
||||
RCTLogWarn(@"Native TextInput(%@) is %zd events ahead of JS - try to make your JS faster.", _textField.text, eventLag);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updatePlaceholder
|
||||
{
|
||||
if (self.placeholder == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary *attributes = [NSMutableDictionary new];
|
||||
if (self.placeholderTextColor) {
|
||||
[attributes setObject:self.placeholderTextColor forKey:NSForegroundColorAttributeName];
|
||||
}
|
||||
|
||||
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder
|
||||
attributes:attributes];
|
||||
}
|
||||
|
||||
- (void)setPlaceholderTextColor:(UIColor *)placeholderTextColor
|
||||
{
|
||||
_placeholderTextColor = placeholderTextColor;
|
||||
[self updatePlaceholder];
|
||||
}
|
||||
|
||||
- (void)setPlaceholder:(NSString *)placeholder
|
||||
{
|
||||
super.placeholder = placeholder;
|
||||
[self updatePlaceholder];
|
||||
[self updateIntrinsicContentSize];
|
||||
}
|
||||
|
||||
- (CGRect)caretRectForPosition:(UITextPosition *)position
|
||||
{
|
||||
if (_caretHidden) {
|
||||
return CGRectZero;
|
||||
}
|
||||
return [super caretRectForPosition:position];
|
||||
}
|
||||
|
||||
#pragma mark - Positioning Overrides
|
||||
|
||||
- (CGRect)textRectForBounds:(CGRect)bounds
|
||||
{
|
||||
return UIEdgeInsetsInsetRect([super textRectForBounds:bounds], self.reactCompoundInsets);
|
||||
}
|
||||
|
||||
- (CGRect)editingRectForBounds:(CGRect)bounds
|
||||
{
|
||||
return [self textRectForBounds:bounds];
|
||||
}
|
||||
|
||||
#pragma mark - Events
|
||||
|
||||
- (void)textFieldDidChange
|
||||
|
@ -204,7 +154,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
_nativeEventCount++;
|
||||
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange
|
||||
reactTag:self.reactTag
|
||||
text:self.text
|
||||
text:_textField.text
|
||||
key:nil
|
||||
eventCount:_nativeEventCount];
|
||||
|
||||
|
@ -215,7 +165,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
|
||||
- (void)textFieldEndEditing
|
||||
{
|
||||
if (![_finalText isEqualToString:self.text]) {
|
||||
if (![_finalText isEqualToString:_textField.text]) {
|
||||
_finalText = nil;
|
||||
// iOS does't send event `UIControlEventEditingChanged` if the change was happened because of autocorrection
|
||||
// which was triggered by loosing focus. We assume that if `text` was changed in the middle of loosing focus process,
|
||||
|
@ -225,7 +175,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
|
||||
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeEnd
|
||||
reactTag:self.reactTag
|
||||
text:self.text
|
||||
text:_textField.text
|
||||
key:nil
|
||||
eventCount:_nativeEventCount];
|
||||
}
|
||||
|
@ -235,7 +185,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
_submitted = YES;
|
||||
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeSubmit
|
||||
reactTag:self.reactTag
|
||||
text:self.text
|
||||
text:_textField.text
|
||||
key:nil
|
||||
eventCount:_nativeEventCount];
|
||||
}
|
||||
|
@ -244,13 +194,13 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
{
|
||||
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeFocus
|
||||
reactTag:self.reactTag
|
||||
text:self.text
|
||||
text:_textField.text
|
||||
key:nil
|
||||
eventCount:_nativeEventCount];
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self->_selectTextOnFocus) {
|
||||
[self selectAll:nil];
|
||||
[self->_textField selectAll:nil];
|
||||
}
|
||||
|
||||
[self sendSelectionEvent];
|
||||
|
@ -258,9 +208,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
}
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||
ofObject:(RCTTextField *)textField
|
||||
change:(NSDictionary *)change
|
||||
context:(void *)context
|
||||
ofObject:(__unused UITextField *)textField
|
||||
change:(__unused NSDictionary *)change
|
||||
context:(__unused void *)context
|
||||
{
|
||||
if ([keyPath isEqualToString:@"selectedTextRange"]) {
|
||||
[self sendSelectionEvent];
|
||||
|
@ -270,14 +220,14 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
- (void)sendSelectionEvent
|
||||
{
|
||||
if (_onSelectionChange &&
|
||||
self.selectedTextRange != _previousSelectionRange &&
|
||||
![self.selectedTextRange isEqual:_previousSelectionRange]) {
|
||||
_textField.selectedTextRange != _previousSelectionRange &&
|
||||
![_textField.selectedTextRange isEqual:_previousSelectionRange]) {
|
||||
|
||||
_previousSelectionRange = self.selectedTextRange;
|
||||
_previousSelectionRange = _textField.selectedTextRange;
|
||||
|
||||
UITextRange *selection = self.selectedTextRange;
|
||||
NSInteger start = [self offsetFromPosition:[self beginningOfDocument] toPosition:selection.start];
|
||||
NSInteger end = [self offsetFromPosition:[self beginningOfDocument] toPosition:selection.end];
|
||||
UITextRange *selection = _textField.selectedTextRange;
|
||||
NSInteger start = [_textField offsetFromPosition:[_textField beginningOfDocument] toPosition:selection.start];
|
||||
NSInteger end = [_textField offsetFromPosition:[_textField beginningOfDocument] toPosition:selection.end];
|
||||
_onSelectionChange(@{
|
||||
@"selection": @{
|
||||
@"start": @(start),
|
||||
|
@ -287,64 +237,88 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
}
|
||||
}
|
||||
|
||||
- (BOOL)resignFirstResponder
|
||||
#pragma mark - Content Size (in Yoga terms, without any insets)
|
||||
|
||||
- (CGSize)contentSize
|
||||
{
|
||||
BOOL result = [super resignFirstResponder];
|
||||
if (result)
|
||||
{
|
||||
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeBlur
|
||||
reactTag:self.reactTag
|
||||
text:self.text
|
||||
key:nil
|
||||
eventCount:_nativeEventCount];
|
||||
// Returning value does NOT include border and padding insets.
|
||||
CGSize contentSize = self.intrinsicContentSize;
|
||||
UIEdgeInsets compoundInsets = self.reactCompoundInsets;
|
||||
contentSize.width -= compoundInsets.left + compoundInsets.right;
|
||||
contentSize.height -= compoundInsets.top + compoundInsets.bottom;
|
||||
return contentSize;
|
||||
}
|
||||
|
||||
- (void)invalidateContentSize
|
||||
{
|
||||
CGSize contentSize = self.contentSize;
|
||||
|
||||
if (CGSizeEqualToSize(_previousContentSize, contentSize)) {
|
||||
return;
|
||||
}
|
||||
return result;
|
||||
_previousContentSize = contentSize;
|
||||
|
||||
[_bridge.uiManager setIntrinsicContentSize:contentSize forView:self];
|
||||
}
|
||||
|
||||
- (void)didMoveToWindow
|
||||
#pragma mark - Layout (in UIKit terms, with all insets)
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
[self reactFocusIfNeeded];
|
||||
// Returning value DOES include border and padding insets.
|
||||
CGSize size = _textField.intrinsicContentSize;
|
||||
size.width += _reactBorderInsets.left + _reactBorderInsets.right;
|
||||
size.height += _reactBorderInsets.top + _reactBorderInsets.bottom;
|
||||
return size;
|
||||
}
|
||||
|
||||
- (void)setFont:(UIFont *)font
|
||||
- (CGSize)sizeThatFits:(CGSize)size
|
||||
{
|
||||
[super setFont:font];
|
||||
[self updateIntrinsicContentSize];
|
||||
CGFloat compoundHorizontalBorderInset = _reactBorderInsets.left + _reactBorderInsets.right;
|
||||
CGFloat compoundVerticalBorderInset = _reactBorderInsets.top + _reactBorderInsets.bottom;
|
||||
|
||||
size.width -= compoundHorizontalBorderInset;
|
||||
size.height -= compoundVerticalBorderInset;
|
||||
|
||||
// Note: `paddingInsets` already included in `_textView` size
|
||||
// because it was applied as `textContainerInset`.
|
||||
CGSize fittingSize = [_textField sizeThatFits:size];
|
||||
|
||||
fittingSize.width += compoundHorizontalBorderInset;
|
||||
fittingSize.height += compoundVerticalBorderInset;
|
||||
|
||||
return fittingSize;
|
||||
}
|
||||
|
||||
- (void)updateIntrinsicContentSize
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
NSString *text = self.placeholder ?: @"";
|
||||
CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: self.font}];
|
||||
size = CGSizeMake(RCTCeilPixelValue(size.width), RCTCeilPixelValue(size.height));
|
||||
[_bridge.uiManager setIntrinsicContentSize:size forView:self];
|
||||
[super layoutSubviews];
|
||||
[self invalidateContentSize];
|
||||
}
|
||||
|
||||
#pragma mark - UITextFieldDelegate (Proxied)
|
||||
#pragma mark - UITextFieldDelegate
|
||||
|
||||
- (BOOL)shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
|
||||
- (BOOL)textField:(RCTTextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
|
||||
{
|
||||
// Only allow single keypresses for `onKeyPress`, pasted text will not be sent.
|
||||
if (_textWasPasted) {
|
||||
_textWasPasted = NO;
|
||||
} else {
|
||||
if (!_textField.textWasPasted) {
|
||||
[self sendKeyValueForString:string];
|
||||
}
|
||||
|
||||
if (_maxLength != nil && ![string isEqualToString:@"\n"]) { // Make sure forms can be submitted via return.
|
||||
NSUInteger allowedLength = _maxLength.integerValue - MIN(_maxLength.integerValue, self.text.length) + range.length;
|
||||
NSUInteger allowedLength = _maxLength.integerValue - MIN(_maxLength.integerValue, _textField.text.length) + range.length;
|
||||
if (string.length > allowedLength) {
|
||||
if (string.length > 1) {
|
||||
// Truncate the input string so the result is exactly `maxLength`.
|
||||
NSString *limitedString = [string substringToIndex:allowedLength];
|
||||
NSMutableString *newString = self.text.mutableCopy;
|
||||
NSMutableString *newString = _textField.text.mutableCopy;
|
||||
[newString replaceCharactersInRange:range withString:limitedString];
|
||||
self.text = newString;
|
||||
_textField.text = newString;
|
||||
|
||||
// Collapse selection at end of insert to match normal paste behavior.
|
||||
UITextPosition *insertEnd = [self positionFromPosition:self.beginningOfDocument
|
||||
offset:(range.location + allowedLength)];
|
||||
self.selectedTextRange = [self textRangeFromPosition:insertEnd toPosition:insertEnd];
|
||||
UITextPosition *insertEnd = [_textField positionFromPosition:_textField.beginningOfDocument
|
||||
offset:(range.location + allowedLength)];
|
||||
_textField.selectedTextRange = [_textField textRangeFromPosition:insertEnd toPosition:insertEnd];
|
||||
[self textFieldDidChange];
|
||||
}
|
||||
return NO;
|
||||
|
@ -356,15 +330,15 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
|
||||
// This method allows us to detect a `Backspace` keyPress
|
||||
// even when there is no more text in the TextField.
|
||||
- (BOOL)keyboardInputShouldDelete
|
||||
- (BOOL)keyboardInputShouldDelete:(RCTTextField *)textField
|
||||
{
|
||||
[self shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""];
|
||||
[self textField:_textField shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)textFieldShouldEndEditing
|
||||
- (BOOL)textFieldShouldEndEditing:(RCTTextField *)textField
|
||||
{
|
||||
_finalText = self.text;
|
||||
_finalText = _textField.text;
|
||||
|
||||
if (_submitted) {
|
||||
_submitted = NO;
|
||||
|
@ -374,4 +348,30 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (void)textFieldDidEndEditing:(UITextField *)textField
|
||||
{
|
||||
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeBlur
|
||||
reactTag:self.reactTag
|
||||
text:self.text
|
||||
key:nil
|
||||
eventCount:_nativeEventCount];
|
||||
}
|
||||
|
||||
#pragma mark - Focus control deledation
|
||||
|
||||
- (void)reactFocus
|
||||
{
|
||||
[_textField reactFocus];
|
||||
}
|
||||
|
||||
- (void)reactBlur
|
||||
{
|
||||
[_textField reactBlur];
|
||||
}
|
||||
|
||||
- (void)didMoveToWindow
|
||||
{
|
||||
[_textField reactFocusIfNeeded];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
#import "RCTConvert+Text.h"
|
||||
#import "RCTShadowTextField.h"
|
||||
#import "RCTTextField.h"
|
||||
|
||||
#import "RCTUITextField.h"
|
||||
|
||||
@implementation RCTTextFieldManager
|
||||
|
||||
|
@ -33,45 +33,45 @@ RCT_EXPORT_MODULE()
|
|||
return [[RCTTextField alloc] initWithBridge:self.bridge];
|
||||
}
|
||||
|
||||
RCT_EXPORT_VIEW_PROPERTY(caretHidden, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(autoCorrect, autocorrectionType, UITextAutocorrectionType)
|
||||
RCT_REMAP_VIEW_PROPERTY(spellCheck, spellCheckingType, UITextSpellCheckingType)
|
||||
RCT_REMAP_VIEW_PROPERTY(editable, enabled, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(placeholder, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(placeholderTextColor, UIColor)
|
||||
RCT_REMAP_VIEW_PROPERTY(caretHidden, textField.caretHidden, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(autoCorrect, textField.autocorrectionType, UITextAutocorrectionType)
|
||||
RCT_REMAP_VIEW_PROPERTY(spellCheck, textField.spellCheckingType, UITextSpellCheckingType)
|
||||
RCT_REMAP_VIEW_PROPERTY(editable, textField.enabled, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(placeholder, textField.placeholder, NSString)
|
||||
RCT_REMAP_VIEW_PROPERTY(placeholderTextColor, textField.placeholderColor, UIColor)
|
||||
RCT_EXPORT_VIEW_PROPERTY(selection, RCTTextSelection)
|
||||
RCT_EXPORT_VIEW_PROPERTY(text, NSString)
|
||||
RCT_EXPORT_VIEW_PROPERTY(maxLength, NSNumber)
|
||||
RCT_EXPORT_VIEW_PROPERTY(clearButtonMode, UITextFieldViewMode)
|
||||
RCT_REMAP_VIEW_PROPERTY(clearTextOnFocus, clearsOnBeginEditing, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(clearButtonMode, textField.clearButtonMode, UITextFieldViewMode)
|
||||
RCT_REMAP_VIEW_PROPERTY(clearTextOnFocus, textField.clearsOnBeginEditing, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(selectTextOnFocus, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(blurOnSubmit, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(keyboardType, UIKeyboardType)
|
||||
RCT_EXPORT_VIEW_PROPERTY(keyboardAppearance, UIKeyboardAppearance)
|
||||
RCT_REMAP_VIEW_PROPERTY(keyboardType, textField.keyboardType, UIKeyboardType)
|
||||
RCT_REMAP_VIEW_PROPERTY(keyboardAppearance, textField.keyboardAppearance, UIKeyboardAppearance)
|
||||
RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock)
|
||||
RCT_EXPORT_VIEW_PROPERTY(returnKeyType, UIReturnKeyType)
|
||||
RCT_EXPORT_VIEW_PROPERTY(enablesReturnKeyAutomatically, BOOL)
|
||||
RCT_EXPORT_VIEW_PROPERTY(secureTextEntry, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(password, secureTextEntry, BOOL) // backwards compatibility
|
||||
RCT_REMAP_VIEW_PROPERTY(color, textColor, UIColor)
|
||||
RCT_REMAP_VIEW_PROPERTY(autoCapitalize, autocapitalizationType, UITextAutocapitalizationType)
|
||||
RCT_REMAP_VIEW_PROPERTY(textAlign, textAlignment, NSTextAlignment)
|
||||
RCT_REMAP_VIEW_PROPERTY(selectionColor, tintColor, UIColor)
|
||||
RCT_REMAP_VIEW_PROPERTY(returnKeyType, textField.returnKeyType, UIReturnKeyType)
|
||||
RCT_REMAP_VIEW_PROPERTY(enablesReturnKeyAutomatically, textField.enablesReturnKeyAutomatically, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(secureTextEntry, textField.secureTextEntry, BOOL)
|
||||
RCT_REMAP_VIEW_PROPERTY(password, textField.secureTextEntry, BOOL) // backwards compatibility
|
||||
RCT_REMAP_VIEW_PROPERTY(color, textField.textColor, UIColor)
|
||||
RCT_REMAP_VIEW_PROPERTY(autoCapitalize, textField.autocapitalizationType, UITextAutocapitalizationType)
|
||||
RCT_REMAP_VIEW_PROPERTY(textAlign, textField.textAlignment, NSTextAlignment)
|
||||
RCT_REMAP_VIEW_PROPERTY(selectionColor, textField.tintColor, UIColor)
|
||||
RCT_CUSTOM_VIEW_PROPERTY(fontSize, NSNumber, RCTTextField)
|
||||
{
|
||||
view.font = [RCTFont updateFont:view.font withSize:json ?: @(defaultView.font.pointSize)];
|
||||
view.textField.font = [RCTFont updateFont:view.textField.font withSize:json ?: @(defaultView.textField.font.pointSize)];
|
||||
}
|
||||
RCT_CUSTOM_VIEW_PROPERTY(fontWeight, NSString, __unused RCTTextField)
|
||||
{
|
||||
view.font = [RCTFont updateFont:view.font withWeight:json]; // defaults to normal
|
||||
view.textField.font = [RCTFont updateFont:view.textField.font withWeight:json]; // defaults to normal
|
||||
}
|
||||
RCT_CUSTOM_VIEW_PROPERTY(fontStyle, NSString, __unused RCTTextField)
|
||||
{
|
||||
view.font = [RCTFont updateFont:view.font withStyle:json]; // defaults to normal
|
||||
view.textField.font = [RCTFont updateFont:view.textField.font withStyle:json]; // defaults to normal
|
||||
}
|
||||
RCT_CUSTOM_VIEW_PROPERTY(fontFamily, NSString, RCTTextField)
|
||||
{
|
||||
view.font = [RCTFont updateFont:view.font withFamily:json ?: defaultView.font.familyName];
|
||||
view.textField.font = [RCTFont updateFont:view.textField.font withFamily:json ?: defaultView.textField.font.familyName];
|
||||
}
|
||||
RCT_EXPORT_VIEW_PROPERTY(mostRecentEventCount, NSInteger)
|
||||
|
||||
|
|
|
@ -547,7 +547,7 @@ static BOOL findMismatch(NSString *first, NSString *second, NSRange *firstRange,
|
|||
[_textView reactFocusIfNeeded];
|
||||
}
|
||||
|
||||
#pragma mark - Content size
|
||||
#pragma mark - Content Size (in Yoga terms, without any insets)
|
||||
|
||||
- (CGSize)contentSize
|
||||
{
|
||||
|
@ -581,7 +581,7 @@ static BOOL findMismatch(NSString *first, NSString *second, NSRange *firstRange,
|
|||
}
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
#pragma mark - Layout (in UIKit terms, with all insets)
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*
|
||||
* Just regular UITextField... but much better!
|
||||
*/
|
||||
@interface RCTUITextField : UITextField
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE;
|
||||
|
||||
@property (nonatomic, assign) BOOL caretHidden;
|
||||
@property (nonatomic, assign, readonly) BOOL textWasPasted;
|
||||
@property (nonatomic, strong, nullable) UIColor *placeholderColor;
|
||||
@property (nonatomic, assign) UIEdgeInsets textContainerInset;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,116 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
#import "RCTUITextField.h"
|
||||
|
||||
#import <React/RCTUtils.h>
|
||||
#import <React/UIView+React.h>
|
||||
|
||||
@implementation RCTUITextField
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
if (self = [super initWithFrame:frame]) {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(_textDidChange)
|
||||
name:UITextFieldTextDidChangeNotification
|
||||
object:self];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)_textDidChange
|
||||
{
|
||||
_textWasPasted = NO;
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setTextContainerInset:(UIEdgeInsets)textContainerInset
|
||||
{
|
||||
_textContainerInset = textContainerInset;
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)setPlaceholder:(NSString *)placeholder
|
||||
{
|
||||
[super setPlaceholder:placeholder];
|
||||
[self _updatePlaceholder];
|
||||
}
|
||||
|
||||
- (void)setPlaceholderColor:(UIColor *)placeholderColor
|
||||
{
|
||||
_placeholderColor = placeholderColor;
|
||||
[self _updatePlaceholder];
|
||||
}
|
||||
|
||||
- (void)_updatePlaceholder
|
||||
{
|
||||
if (self.placeholder == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSMutableDictionary *attributes = [NSMutableDictionary new];
|
||||
if (_placeholderColor) {
|
||||
[attributes setObject:_placeholderColor forKey:NSForegroundColorAttributeName];
|
||||
}
|
||||
|
||||
self.attributedPlaceholder = [[NSAttributedString alloc] initWithString:self.placeholder
|
||||
attributes:attributes];
|
||||
}
|
||||
|
||||
#pragma mark - Caret Manipulation
|
||||
|
||||
- (CGRect)caretRectForPosition:(UITextPosition *)position
|
||||
{
|
||||
if (_caretHidden) {
|
||||
return CGRectZero;
|
||||
}
|
||||
|
||||
return [super caretRectForPosition:position];
|
||||
}
|
||||
|
||||
#pragma mark - Positioning Overrides
|
||||
|
||||
- (CGRect)textRectForBounds:(CGRect)bounds
|
||||
{
|
||||
return UIEdgeInsetsInsetRect([super textRectForBounds:bounds], _textContainerInset);
|
||||
}
|
||||
|
||||
- (CGRect)editingRectForBounds:(CGRect)bounds
|
||||
{
|
||||
return [self textRectForBounds:bounds];
|
||||
}
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
// Note: `placeholder` defines intrinsic size for `<TextInput>`.
|
||||
NSString *text = self.placeholder ?: @"";
|
||||
CGSize size = [text sizeWithAttributes:@{NSFontAttributeName: self.font}];
|
||||
size = CGSizeMake(RCTCeilPixelValue(size.width), RCTCeilPixelValue(size.height));
|
||||
size.width += _textContainerInset.left + _textContainerInset.right;
|
||||
size.height += _textContainerInset.top + _textContainerInset.bottom;
|
||||
return size;
|
||||
}
|
||||
|
||||
- (CGSize)sizeThatFits:(CGSize)size
|
||||
{
|
||||
CGSize intrinsicSize = self.intrinsicContentSize;
|
||||
return CGSizeMake(MIN(size.width, intrinsicSize.width), MIN(size.height, intrinsicSize.height));
|
||||
}
|
||||
|
||||
@end
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
#import "RCTUITextView.h"
|
||||
|
||||
#import <React/UIView+React.h>
|
||||
#import <React/RCTUtils.h>
|
||||
#import <React/UIView+React.h>
|
||||
|
||||
@implementation RCTUITextView
|
||||
{
|
||||
|
|
|
@ -773,6 +773,9 @@ exports.examples = [
|
|||
backgroundColor: '#eeeeee',
|
||||
borderColor: '#666666',
|
||||
borderWidth: 5,
|
||||
borderTopWidth: 20,
|
||||
borderRadius: 10,
|
||||
borderBottomRightRadius: 20,
|
||||
padding: 10,
|
||||
paddingTop: 20,
|
||||
}}
|
||||
|
@ -780,7 +783,7 @@ exports.examples = [
|
|||
/>
|
||||
</View>
|
||||
<Text>Multiline TextInput</Text>
|
||||
<View style={{height: 80}}>
|
||||
<View style={{height: 130}}>
|
||||
<TextInput
|
||||
style={{
|
||||
position: 'absolute',
|
||||
|
@ -788,9 +791,12 @@ exports.examples = [
|
|||
backgroundColor: '#eeeeee',
|
||||
borderColor: '#666666',
|
||||
borderWidth: 5,
|
||||
borderTopWidth: 20,
|
||||
borderRadius: 10,
|
||||
borderBottomRightRadius: 20,
|
||||
padding: 10,
|
||||
paddingTop: 20,
|
||||
borderTopWidth: 20,
|
||||
maxHeight: 100
|
||||
}}
|
||||
multiline={true}
|
||||
placeholder="Placeholder defines intrinsic size"
|
||||
|
|
|
@ -706,6 +706,12 @@
|
|||
597AD1BE1E577D7800152581 /* RCTRootContentView.h in Headers */ = {isa = PBXBuildFile; fileRef = 597AD1BB1E577D7800152581 /* RCTRootContentView.h */; };
|
||||
597AD1BF1E577D7800152581 /* RCTRootContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 597AD1BC1E577D7800152581 /* RCTRootContentView.m */; };
|
||||
597AD1C01E577D7800152581 /* RCTRootContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = 597AD1BC1E577D7800152581 /* RCTRootContentView.m */; };
|
||||
598C22D61EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 598C22D41EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.h */; };
|
||||
598C22D71EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 598C22D41EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.h */; };
|
||||
598C22D81EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.m in Sources */ = {isa = PBXBuildFile; fileRef = 598C22D51EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.m */; };
|
||||
598C22D91EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.m in Sources */ = {isa = PBXBuildFile; fileRef = 598C22D51EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.m */; };
|
||||
598C22DA1EDCBF61009AF445 /* RCTUIManagerObserverCoordinator.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 598C22D41EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.h */; };
|
||||
598C22DB1EDCBF82009AF445 /* RCTUIManagerObserverCoordinator.h in Copy Headers */ = {isa = PBXBuildFile; fileRef = 598C22D41EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.h */; };
|
||||
68EFE4EE1CF6EB3900A1DE13 /* RCTBundleURLProvider.m in Sources */ = {isa = PBXBuildFile; fileRef = 68EFE4ED1CF6EB3900A1DE13 /* RCTBundleURLProvider.m */; };
|
||||
830A229E1A66C68A008503DA /* RCTRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = 830A229D1A66C68A008503DA /* RCTRootView.m */; };
|
||||
83392EB31B6634E10013B15F /* RCTModalHostViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 83392EB21B6634E10013B15F /* RCTModalHostViewController.m */; };
|
||||
|
@ -814,6 +820,7 @@
|
|||
dstPath = include/React;
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
598C22DB1EDCBF82009AF445 /* RCTUIManagerObserverCoordinator.h in Copy Headers */,
|
||||
5954055C1EC03A8E00766D3C /* RCTShadowView+Layout.h in Copy Headers */,
|
||||
2D7B05391E9D82080032604E /* RCTBridge+Private.h in Copy Headers */,
|
||||
3D0976C31E9739AE00B9C6DD /* RCTBridge+JavaScriptCore.h in Copy Headers */,
|
||||
|
@ -977,6 +984,7 @@
|
|||
dstPath = include/React;
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
598C22DA1EDCBF61009AF445 /* RCTUIManagerObserverCoordinator.h in Copy Headers */,
|
||||
5954055B1EC03A7F00766D3C /* RCTShadowView+Layout.h in Copy Headers */,
|
||||
3D7BFCEB1EA8E23A008DFB7A /* RCTDevSettings.h in Copy Headers */,
|
||||
3D0976C41E9739B400B9C6DD /* RCTBridge+JavaScriptCore.h in Copy Headers */,
|
||||
|
@ -1347,6 +1355,8 @@
|
|||
595405561EC03A1700766D3C /* RCTShadowView+Layout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTShadowView+Layout.m"; sourceTree = "<group>"; };
|
||||
597AD1BB1E577D7800152581 /* RCTRootContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTRootContentView.h; sourceTree = "<group>"; };
|
||||
597AD1BC1E577D7800152581 /* RCTRootContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTRootContentView.m; sourceTree = "<group>"; };
|
||||
598C22D41EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTUIManagerObserverCoordinator.h; sourceTree = "<group>"; };
|
||||
598C22D51EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUIManagerObserverCoordinator.m; sourceTree = "<group>"; };
|
||||
65F3E41D1E73031C009375BD /* systemJSCWrapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = systemJSCWrapper.cpp; sourceTree = "<group>"; };
|
||||
68EFE4EC1CF6EB3000A1DE13 /* RCTBundleURLProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTBundleURLProvider.h; sourceTree = "<group>"; };
|
||||
68EFE4ED1CF6EB3900A1DE13 /* RCTBundleURLProvider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTBundleURLProvider.m; sourceTree = "<group>"; };
|
||||
|
@ -1459,8 +1469,6 @@
|
|||
13B07FE01A69315300A75B9A /* Modules */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
369123DF1DDC75850095B341 /* RCTJSCSamplingProfiler.h */,
|
||||
369123E01DDC75850095B341 /* RCTJSCSamplingProfiler.m */,
|
||||
E9B20B791B500126007A2DA7 /* RCTAccessibilityManager.h */,
|
||||
E9B20B7A1B500126007A2DA7 /* RCTAccessibilityManager.m */,
|
||||
13B07FE71A69327A00A75B9A /* RCTAlertManager.h */,
|
||||
|
@ -1471,10 +1479,10 @@
|
|||
58114A4E1AAE93D500E7D092 /* RCTAsyncLocalStorage.m */,
|
||||
13D033611C1837FE0021DC29 /* RCTClipboard.h */,
|
||||
13D033621C1837FE0021DC29 /* RCTClipboard.m */,
|
||||
B505583C1E43DFB900F71A00 /* RCTDevSettings.h */,
|
||||
B505583D1E43DFB900F71A00 /* RCTDevSettings.mm */,
|
||||
CF85BC301E79EC6B00F1EF3B /* RCTDeviceInfo.h */,
|
||||
CF85BC311E79EC6B00F1EF3B /* RCTDeviceInfo.m */,
|
||||
B505583C1E43DFB900F71A00 /* RCTDevSettings.h */,
|
||||
B505583D1E43DFB900F71A00 /* RCTDevSettings.mm */,
|
||||
13D9FEE91CDCCECF00158BD7 /* RCTEventEmitter.h */,
|
||||
13D9FEEA1CDCCECF00158BD7 /* RCTEventEmitter.m */,
|
||||
13B07FE91A69327A00A75B9A /* RCTExceptionsManager.h */,
|
||||
|
@ -1483,6 +1491,8 @@
|
|||
B233E6E91D2D845D00BC68BA /* RCTI18nManager.m */,
|
||||
352DCFEE1D19F4C20056D623 /* RCTI18nUtil.h */,
|
||||
352DCFEF1D19F4C20056D623 /* RCTI18nUtil.m */,
|
||||
369123DF1DDC75850095B341 /* RCTJSCSamplingProfiler.h */,
|
||||
369123E01DDC75850095B341 /* RCTJSCSamplingProfiler.m */,
|
||||
13D9FEEC1CDCD93000158BD7 /* RCTKeyboardObserver.h */,
|
||||
13D9FEED1CDCD93000158BD7 /* RCTKeyboardObserver.m */,
|
||||
13F17A831B8493E5007D4C75 /* RCTRedBox.h */,
|
||||
|
@ -1497,6 +1507,8 @@
|
|||
3D5AC7161E0056D9000F9153 /* RCTTVNavigationEventEmitter.m */,
|
||||
13E067481A70F434002CDEE1 /* RCTUIManager.h */,
|
||||
13E067491A70F434002CDEE1 /* RCTUIManager.m */,
|
||||
598C22D41EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.h */,
|
||||
598C22D51EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.m */,
|
||||
);
|
||||
path = Modules;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1888,6 +1900,7 @@
|
|||
A12E9E911E5DFA720029001B /* RCTSamplingProfilerPackagerMethod.h in Headers */,
|
||||
3D302F371DF828F800D6DDAE /* RCTEventDispatcher.h in Headers */,
|
||||
3D302F381DF828F800D6DDAE /* RCTFrameUpdate.h in Headers */,
|
||||
598C22D71EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.h in Headers */,
|
||||
3D5AC7221E005763000F9153 /* RCTTVRemoteHandler.h in Headers */,
|
||||
2D074E381E609E65001D6DD0 /* RCTReconnectingWebSocket.h in Headers */,
|
||||
3D302F391DF828F800D6DDAE /* RCTImageSource.h in Headers */,
|
||||
|
@ -2119,6 +2132,7 @@
|
|||
3D80DA511DF820620028D040 /* RCTEventEmitter.h in Headers */,
|
||||
3D80DA521DF820620028D040 /* RCTExceptionsManager.h in Headers */,
|
||||
3D80DA531DF820620028D040 /* RCTI18nManager.h in Headers */,
|
||||
598C22D61EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.h in Headers */,
|
||||
3D80DA541DF820620028D040 /* RCTI18nUtil.h in Headers */,
|
||||
3D80DA551DF820620028D040 /* RCTKeyboardObserver.h in Headers */,
|
||||
3D80DA561DF820620028D040 /* RCTRedBox.h in Headers */,
|
||||
|
@ -2497,6 +2511,7 @@
|
|||
2D3B5E9F1D9B08AF00451313 /* RCTKeyCommands.m in Sources */,
|
||||
2D3B5EA51D9B08C700451313 /* RCTRootView.m in Sources */,
|
||||
2D3B5EAC1D9B08EF00451313 /* RCTJSCExecutor.mm in Sources */,
|
||||
598C22D91EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.m in Sources */,
|
||||
2D3B5EB11D9B090100451313 /* RCTAppState.m in Sources */,
|
||||
2D3B5EC21D9B093B00451313 /* RCTProfile.m in Sources */,
|
||||
2D3B5ECB1D9B096200451313 /* RCTConvert+CoreLocation.m in Sources */,
|
||||
|
@ -2634,6 +2649,7 @@
|
|||
83CBBA511A601E3B00E9B192 /* RCTAssert.m in Sources */,
|
||||
13AF20451AE707F9005F5298 /* RCTSlider.m in Sources */,
|
||||
58114A501AAE93D500E7D092 /* RCTAsyncLocalStorage.m in Sources */,
|
||||
598C22D81EDCBEE1009AF445 /* RCTUIManagerObserverCoordinator.m in Sources */,
|
||||
13513F3C1B1F43F400FCE529 /* RCTProgressViewManager.m in Sources */,
|
||||
14F7A0F01BDA714B003C6C10 /* RCTFPSGraph.m in Sources */,
|
||||
14F3620D1AABD06A001CE568 /* RCTSwitch.m in Sources */,
|
||||
|
|
Loading…
Reference in New Issue