Skip to content

Commit e3fd144

Browse files
shergingrabbou
authored andcommitted
TextInput: Refined contentSize calculation
Summary: This fixes pretty bad issue when contentSize is calculated based on an intrinsic horizontal (width) limitation, not on a real/current horizontal (width) one. Reviewed By: mmmulani Differential Revision: D5422114 fbshipit-source-id: 0eb582aeb59d29530990d4faabf2f41baa79c058
1 parent 7442dc8 commit e3fd144

5 files changed

Lines changed: 46 additions & 5 deletions

File tree

Libraries/Text/RCTBackedTextInputViewProtocol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@
1919
@property (nonatomic, strong, nullable) UIFont *font;
2020
@property (nonatomic, assign) UIEdgeInsets textContainerInset;
2121
@property (nonatomic, strong, nullable) UIView *inputAccessoryView;
22+
@property (nonatomic, readonly) CGSize contentSize;
2223

2324
@end

Libraries/Text/RCTTextInput.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,10 @@ - (void)setReactBorderInsets:(UIEdgeInsets)reactBorderInsets
6464

6565
- (CGSize)contentSize
6666
{
67-
CGSize contentSize = self.intrinsicContentSize;
68-
UIEdgeInsets compoundInsets = self.reactCompoundInsets;
69-
contentSize.width -= compoundInsets.left + compoundInsets.right;
70-
contentSize.height -= compoundInsets.top + compoundInsets.bottom;
67+
CGSize contentSize = self.backedTextInputView.contentSize;
68+
UIEdgeInsets reactPaddingInsets = self.reactPaddingInsets;
69+
contentSize.width -= reactPaddingInsets.left + reactPaddingInsets.right;
70+
contentSize.height -= reactPaddingInsets.top + reactPaddingInsets.bottom;
7171
// Returning value does NOT include border and padding insets.
7272
return contentSize;
7373
}

Libraries/Text/RCTUITextField.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ - (void)paste:(id)sender
114114

115115
#pragma mark - Layout
116116

117+
- (CGSize)contentSize
118+
{
119+
// Returning size DOES contain `textContainerInset` (aka `padding`).
120+
return self.intrinsicContentSize;
121+
}
122+
117123
- (CGSize)intrinsicContentSize
118124
{
119125
// Note: `placeholder` defines intrinsic size for `<TextInput>`.
@@ -122,11 +128,13 @@ - (CGSize)intrinsicContentSize
122128
size = CGSizeMake(RCTCeilPixelValue(size.width), RCTCeilPixelValue(size.height));
123129
size.width += _textContainerInset.left + _textContainerInset.right;
124130
size.height += _textContainerInset.top + _textContainerInset.bottom;
131+
// Returning size DOES contain `textContainerInset` (aka `padding`).
125132
return size;
126133
}
127134

128135
- (CGSize)sizeThatFits:(CGSize)size
129136
{
137+
// All size values here contain `textContainerInset` (aka `padding`).
130138
CGSize intrinsicSize = self.intrinsicContentSize;
131139
return CGSizeMake(MIN(size.width, intrinsicSize.width), MIN(size.height, intrinsicSize.height));
132140
}

Libraries/Text/RCTUITextView.m

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ - (void)setContentOffset:(CGPoint)contentOffset animated:(__unused BOOL)animated
134134

135135
- (CGFloat)preferredMaxLayoutWidth
136136
{
137+
// Returning size DOES contain `textContainerInset` (aka `padding`).
137138
return _preferredMaxLayoutWidth ?: self.placeholderSize.width;
138139
}
139140

@@ -149,6 +150,18 @@ - (CGSize)placeholderSize
149150
return placeholderSize;
150151
}
151152

153+
- (CGSize)contentSize
154+
{
155+
CGSize contentSize = super.contentSize;
156+
CGSize placeholderSize = self.placeholderSize;
157+
// When a text input is empty, it actually displays a placehoder.
158+
// So, we have to consider `placeholderSize` as a minimum `contentSize`.
159+
// Returning size DOES contain `textContainerInset` (aka `padding`).
160+
return CGSizeMake(
161+
MAX(contentSize.width, placeholderSize.width),
162+
MAX(contentSize.height, placeholderSize.height));
163+
}
164+
152165
- (void)layoutSubviews
153166
{
154167
[super layoutSubviews];
@@ -161,6 +174,7 @@ - (void)layoutSubviews
161174

162175
- (CGSize)intrinsicContentSize
163176
{
177+
// Returning size DOES contain `textContainerInset` (aka `padding`).
164178
return [self sizeThatFits:CGSizeMake(self.preferredMaxLayoutWidth, INFINITY)];
165179
}
166180

@@ -169,7 +183,7 @@ - (CGSize)sizeThatFits:(CGSize)size
169183
// Returned fitting size depends on text size and placeholder size.
170184
CGSize textSize = [self fixedSizeThatFits:size];
171185
CGSize placeholderSize = self.placeholderSize;
172-
// Returning size DOES contain `textContainerInset`.
186+
// Returning size DOES contain `textContainerInset` (aka `padding`).
173187
return CGSizeMake(MAX(textSize.width, placeholderSize.width), MAX(textSize.height, placeholderSize.height));
174188
}
175189

RNTester/js/TextInputExample.ios.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -805,6 +805,24 @@ exports.examples = [
805805
placeholder="Placeholder defines intrinsic size"
806806
/>
807807
</View>
808+
<View>
809+
<TextInput
810+
style={{
811+
fontSize: 16,
812+
backgroundColor: '#eeeeee',
813+
borderColor: '#666666',
814+
borderWidth: 5,
815+
borderTopWidth: 20,
816+
borderRadius: 10,
817+
borderBottomRightRadius: 20,
818+
padding: 10,
819+
paddingTop: 20,
820+
}}
821+
testID="multiline_textinput_with_flex"
822+
multiline={true}
823+
placeholder="Placeholder defines intrinsic size"
824+
/>
825+
</View>
808826
</View>
809827
);
810828
}

0 commit comments

Comments
 (0)