diff --git a/Examples/UIExplorer/TextInputExample.ios.js b/Examples/UIExplorer/TextInputExample.ios.js index 5f13d822f..471920a0b 100644 --- a/Examples/UIExplorer/TextInputExample.ios.js +++ b/Examples/UIExplorer/TextInputExample.ios.js @@ -301,6 +301,50 @@ exports.displayName = (undefined: ?string); exports.title = ''; exports.description = 'Single and multi-line text inputs.'; exports.examples = [ + { + title: 'Multiline', + render: function() { + return ( + + + + + + + + + ); + } + }, + { + title: 'Attributed text', + render: function() { + return ; + } + }, { title: 'Auto-focus', render: function() { @@ -544,50 +588,6 @@ exports.examples = [ ); } }, - { - title: 'Multiline', - render: function() { - return ( - - - - - - - - - ); - } - }, - { - title: 'Attributed text', - render: function() { - return ; - } - }, { title: 'Blur on submit', render: function(): ReactElement { return ; }, diff --git a/Libraries/Text/RCTTextView.h b/Libraries/Text/RCTTextView.h index a6d8bca08..9305442ab 100644 --- a/Libraries/Text/RCTTextView.h +++ b/Libraries/Text/RCTTextView.h @@ -22,7 +22,6 @@ @property (nonatomic, assign) UIEdgeInsets contentInset; @property (nonatomic, assign) BOOL automaticallyAdjustContentInsets; @property (nonatomic, copy) NSString *text; -@property (nonatomic, strong) UIColor *textColor; @property (nonatomic, strong) UIColor *placeholderTextColor; @property (nonatomic, strong) UIFont *font; @property (nonatomic, assign) NSInteger mostRecentEventCount; diff --git a/Libraries/Text/RCTTextView.m b/Libraries/Text/RCTTextView.m index 2af31f39a..f75a4c013 100644 --- a/Libraries/Text/RCTTextView.m +++ b/Libraries/Text/RCTTextView.m @@ -44,6 +44,7 @@ NSMutableArray *_subviews; BOOL _blockTextShouldChange; UITextRange *_previousSelectionRange; + UIScrollView *_scrollView; } - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher @@ -55,15 +56,19 @@ _eventDispatcher = eventDispatcher; _placeholderTextColor = [self defaultPlaceholderTextColor]; - _textView = [[RCTUITextView alloc] initWithFrame:self.bounds]; + _textView = [[RCTUITextView alloc] initWithFrame:CGRectZero]; _textView.backgroundColor = [UIColor clearColor]; _textView.scrollsToTop = NO; + _textView.scrollEnabled = NO; _textView.delegate = self; + _scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero]; + [_scrollView addSubview:_textView]; + _previousSelectionRange = _textView.selectedTextRange; _subviews = [NSMutableArray new]; - [self addSubview:_textView]; + [self addSubview:_scrollView]; } return self; } @@ -139,16 +144,11 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) // we temporarily block all textShouldChange events so they are not applied. _blockTextShouldChange = YES; - // We compute the new selectedRange manually to make sure the cursor is at the - // end of the newly inserted/deleted text after update. NSRange range = _textView.selectedRange; - CGPoint contentOffset = _textView.contentOffset; - _textView.attributedText = _pendingAttributedText; _pendingAttributedText = nil; _textView.selectedRange = range; [_textView layoutIfNeeded]; - _textView.contentOffset = contentOffset; [self _setPlaceholderVisibility]; @@ -174,11 +174,21 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) CGRect frame = UIEdgeInsetsInsetRect(self.bounds, adjustedFrameInset); _textView.frame = frame; _placeholderView.frame = frame; + _scrollView.frame = frame; + [self updateContentSize]; _textView.textContainerInset = adjustedTextContainerInset; _placeholderView.textContainerInset = adjustedTextContainerInset; } +- (void)updateContentSize +{ + _textView.scrollEnabled = YES; + _scrollView.contentSize = _textView.contentSize; + _textView.frame = (CGRect){CGPointZero, _scrollView.contentSize}; + _textView.scrollEnabled = NO; +} + - (void)updatePlaceholder { [_placeholderView removeFromSuperview]; @@ -186,6 +196,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) if (_placeholder) { _placeholderView = [[UITextView alloc] initWithFrame:self.bounds]; + _placeholderView.editable = NO; + _placeholderView.userInteractionEnabled = NO; _placeholderView.backgroundColor = [UIColor clearColor]; _placeholderView.scrollEnabled = false; _placeholderView.scrollsToTop = NO; @@ -211,16 +223,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) [self updatePlaceholder]; } -- (UIColor *)textColor -{ - return _textView.textColor; -} - -- (void)setTextColor:(UIColor *)textColor -{ - _textView.textColor = textColor; -} - - (void)setPlaceholder:(NSString *)placeholder { _placeholder = placeholder; @@ -305,10 +307,6 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) }, }); } - - if (textView.editable && [textView isFirstResponder]) { - [textView scrollRangeToVisible:textView.selectedRange]; - } } - (void)setText:(NSString *)text @@ -369,6 +367,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder) - (void)textViewDidChange:(UITextView *)textView { + [self updateContentSize]; [self _setPlaceholderVisibility]; _nativeEventCount++; [_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange diff --git a/Libraries/Text/RCTTextViewManager.m b/Libraries/Text/RCTTextViewManager.m index c5c04ee7f..94ba4609c 100644 --- a/Libraries/Text/RCTTextViewManager.m +++ b/Libraries/Text/RCTTextViewManager.m @@ -23,21 +23,22 @@ RCT_EXPORT_MODULE() return [[RCTTextView alloc] initWithEventDispatcher:self.bridge.eventDispatcher]; } +RCT_REMAP_VIEW_PROPERTY(autoCapitalize, textView.autocapitalizationType, UITextAutocapitalizationType) RCT_EXPORT_VIEW_PROPERTY(autoCorrect, BOOL) -RCT_REMAP_VIEW_PROPERTY(editable, textView.editable, BOOL) -RCT_EXPORT_VIEW_PROPERTY(placeholder, NSString) -RCT_EXPORT_VIEW_PROPERTY(placeholderTextColor, UIColor) -RCT_EXPORT_VIEW_PROPERTY(text, NSString) -RCT_EXPORT_VIEW_PROPERTY(maxLength, NSNumber) RCT_EXPORT_VIEW_PROPERTY(clearTextOnFocus, BOOL) -RCT_EXPORT_VIEW_PROPERTY(selectTextOnFocus, BOOL) +RCT_REMAP_VIEW_PROPERTY(color, textView.textColor, UIColor) +RCT_REMAP_VIEW_PROPERTY(editable, textView.editable, BOOL) +RCT_REMAP_VIEW_PROPERTY(enablesReturnKeyAutomatically, textView.enablesReturnKeyAutomatically, BOOL) RCT_REMAP_VIEW_PROPERTY(keyboardType, textView.keyboardType, UIKeyboardType) RCT_REMAP_VIEW_PROPERTY(keyboardAppearance, textView.keyboardAppearance, UIKeyboardAppearance) +RCT_EXPORT_VIEW_PROPERTY(maxLength, NSNumber) RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock) +RCT_EXPORT_VIEW_PROPERTY(placeholder, NSString) +RCT_EXPORT_VIEW_PROPERTY(placeholderTextColor, UIColor) RCT_REMAP_VIEW_PROPERTY(returnKeyType, textView.returnKeyType, UIReturnKeyType) -RCT_REMAP_VIEW_PROPERTY(enablesReturnKeyAutomatically, textView.enablesReturnKeyAutomatically, BOOL) -RCT_REMAP_VIEW_PROPERTY(color, textColor, UIColor) -RCT_REMAP_VIEW_PROPERTY(autoCapitalize, textView.autocapitalizationType, UITextAutocapitalizationType) +RCT_REMAP_VIEW_PROPERTY(secureTextEntry, textView.secureTextEntry, BOOL) +RCT_EXPORT_VIEW_PROPERTY(selectTextOnFocus, BOOL) +RCT_EXPORT_VIEW_PROPERTY(text, NSString) RCT_CUSTOM_VIEW_PROPERTY(fontSize, CGFloat, RCTTextView) { view.font = [RCTConvert UIFont:view.font withSize:json ?: @(defaultView.font.pointSize)];