Singleline <TextInput> now has intrinsic size

Summary:
Singleline <TextInput> now has intrinsic size which is equal to size of placeholder.
And if <TextInput> does not have placeholder it still has intrinsic height.
So, we don't need to set the size up manually every single time anymore!

(Multiline <TextInput> already has this feature.)

Reviewed By: mmmulani

Differential Revision: D5069971

fbshipit-source-id: f65c1062a812259b66d287929314dc571dc1f3ee
This commit is contained in:
Valentin Shergin
2017-05-29 15:56:38 -07:00
committed by Facebook Github Bot
parent c98fc33ce5
commit ea9d6746df
4 changed files with 41 additions and 9 deletions

View File

@@ -11,7 +11,7 @@
#import <React/RCTComponent.h>
@class RCTEventDispatcher;
@class RCTBridge;
@interface RCTTextField : UITextField
@@ -25,6 +25,6 @@
@property (nonatomic, copy) RCTDirectEventBlock onSelectionChange;
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
@end

View File

@@ -9,8 +9,10 @@
#import "RCTTextField.h"
#import <React/RCTBridge.h>
#import <React/RCTConvert.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTUIManager.h>
#import <React/RCTUtils.h>
#import <React/UIView+React.h>
@@ -47,6 +49,7 @@
@implementation RCTTextField
{
RCTBridge *_bridge;
RCTEventDispatcher *_eventDispatcher;
NSInteger _nativeEventCount;
BOOL _submitted;
@@ -56,17 +59,20 @@
RCTTextFieldDelegateProxy *_delegateProxy;
}
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
- (instancetype)initWithBridge:(RCTBridge *)bridge
{
if ((self = [super initWithFrame:CGRectZero])) {
RCTAssert(eventDispatcher, @"eventDispatcher is a required parameter");
_eventDispatcher = eventDispatcher;
if (self = [super initWithFrame:CGRectZero]) {
RCTAssertParam(bridge);
_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];
_blurOnSubmit = YES;
// 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.
@@ -165,6 +171,7 @@ static void RCTUpdatePlaceholder(RCTTextField *self)
{
super.placeholder = placeholder;
RCTUpdatePlaceholder(self);
[self updateIntrinsicContentSize];
}
- (CGRect)caretRectForPosition:(UITextPosition *)position
@@ -186,6 +193,8 @@ static void RCTUpdatePlaceholder(RCTTextField *self)
return [self textRectForBounds:bounds];
}
#pragma mark - Events
- (void)textFieldDidChange
{
_nativeEventCount++;
@@ -293,6 +302,20 @@ static void RCTUpdatePlaceholder(RCTTextField *self)
[self reactFocusIfNeeded];
}
- (void)setFont:(UIFont *)font
{
[super setFont:font];
[self updateIntrinsicContentSize];
}
- (void)updateIntrinsicContentSize
{
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];
}
#pragma mark - UITextFieldDelegate (Proxied)
- (BOOL)shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

View File

@@ -30,7 +30,7 @@ RCT_EXPORT_MODULE()
- (UIView *)view
{
return [[RCTTextField alloc] initWithEventDispatcher:self.bridge.eventDispatcher];
return [[RCTTextField alloc] initWithBridge:self.bridge];
}
RCT_EXPORT_VIEW_PROPERTY(caretHidden, BOOL)