mirror of
https://github.com/status-im/react-native.git
synced 2025-02-03 21:24:31 +00:00
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
This commit is contained in:
parent
f5d9b5210e
commit
603cc48ceb
@ -22,6 +22,7 @@
|
||||
@property (nonatomic, assign) UIEdgeInsets textContainerInset;
|
||||
@property (nonatomic, strong, nullable) UIView *inputAccessoryView;
|
||||
@property (nonatomic, weak, nullable) id<RCTBackedTextInputDelegate> textInputDelegate;
|
||||
@property (nonatomic, readonly) CGSize contentSize;
|
||||
|
||||
// This protocol disallows direct access to `selectedTextRange` property because
|
||||
// unwise usage of it can break the `delegate` behavior. So, we always have to
|
||||
|
@ -168,10 +168,10 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
|
||||
|
||||
- (CGSize)contentSize
|
||||
{
|
||||
CGSize contentSize = self.intrinsicContentSize;
|
||||
UIEdgeInsets compoundInsets = self.reactCompoundInsets;
|
||||
contentSize.width -= compoundInsets.left + compoundInsets.right;
|
||||
contentSize.height -= compoundInsets.top + compoundInsets.bottom;
|
||||
CGSize contentSize = self.backedTextInputView.contentSize;
|
||||
UIEdgeInsets reactPaddingInsets = self.reactPaddingInsets;
|
||||
contentSize.width -= reactPaddingInsets.left + reactPaddingInsets.right;
|
||||
contentSize.height -= reactPaddingInsets.top + reactPaddingInsets.bottom;
|
||||
// Returning value does NOT include border and padding insets.
|
||||
return contentSize;
|
||||
}
|
||||
|
@ -137,6 +137,12 @@
|
||||
|
||||
#pragma mark - Layout
|
||||
|
||||
- (CGSize)contentSize
|
||||
{
|
||||
// Returning size DOES contain `textContainerInset` (aka `padding`).
|
||||
return self.intrinsicContentSize;
|
||||
}
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
// Note: `placeholder` defines intrinsic size for `<TextInput>`.
|
||||
@ -145,11 +151,13 @@
|
||||
size = CGSizeMake(RCTCeilPixelValue(size.width), RCTCeilPixelValue(size.height));
|
||||
size.width += _textContainerInset.left + _textContainerInset.right;
|
||||
size.height += _textContainerInset.top + _textContainerInset.bottom;
|
||||
// Returning size DOES contain `textContainerInset` (aka `padding`).
|
||||
return size;
|
||||
}
|
||||
|
||||
- (CGSize)sizeThatFits:(CGSize)size
|
||||
{
|
||||
// All size values here contain `textContainerInset` (aka `padding`).
|
||||
CGSize intrinsicSize = self.intrinsicContentSize;
|
||||
return CGSizeMake(MIN(size.width, intrinsicSize.width), MIN(size.height, intrinsicSize.height));
|
||||
}
|
||||
|
@ -152,6 +152,7 @@ static UIColor *defaultPlaceholderColor()
|
||||
|
||||
- (CGFloat)preferredMaxLayoutWidth
|
||||
{
|
||||
// Returning size DOES contain `textContainerInset` (aka `padding`).
|
||||
return _preferredMaxLayoutWidth ?: self.placeholderSize.width;
|
||||
}
|
||||
|
||||
@ -167,6 +168,18 @@ static UIColor *defaultPlaceholderColor()
|
||||
return placeholderSize;
|
||||
}
|
||||
|
||||
- (CGSize)contentSize
|
||||
{
|
||||
CGSize contentSize = super.contentSize;
|
||||
CGSize placeholderSize = self.placeholderSize;
|
||||
// When a text input is empty, it actually displays a placehoder.
|
||||
// So, we have to consider `placeholderSize` as a minimum `contentSize`.
|
||||
// Returning size DOES contain `textContainerInset` (aka `padding`).
|
||||
return CGSizeMake(
|
||||
MAX(contentSize.width, placeholderSize.width),
|
||||
MAX(contentSize.height, placeholderSize.height));
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
@ -179,6 +192,7 @@ static UIColor *defaultPlaceholderColor()
|
||||
|
||||
- (CGSize)intrinsicContentSize
|
||||
{
|
||||
// Returning size DOES contain `textContainerInset` (aka `padding`).
|
||||
return [self sizeThatFits:CGSizeMake(self.preferredMaxLayoutWidth, INFINITY)];
|
||||
}
|
||||
|
||||
@ -187,7 +201,7 @@ static UIColor *defaultPlaceholderColor()
|
||||
// Returned fitting size depends on text size and placeholder size.
|
||||
CGSize textSize = [self fixedSizeThatFits:size];
|
||||
CGSize placeholderSize = self.placeholderSize;
|
||||
// Returning size DOES contain `textContainerInset`.
|
||||
// Returning size DOES contain `textContainerInset` (aka `padding`).
|
||||
return CGSizeMake(MAX(textSize.width, placeholderSize.width), MAX(textSize.height, placeholderSize.height));
|
||||
}
|
||||
|
||||
|
@ -823,6 +823,24 @@ exports.examples = [
|
||||
placeholder="Placeholder defines intrinsic size"
|
||||
/>
|
||||
</View>
|
||||
<View>
|
||||
<TextInput
|
||||
style={{
|
||||
fontSize: 16,
|
||||
backgroundColor: '#eeeeee',
|
||||
borderColor: '#666666',
|
||||
borderWidth: 5,
|
||||
borderTopWidth: 20,
|
||||
borderRadius: 10,
|
||||
borderBottomRightRadius: 20,
|
||||
padding: 10,
|
||||
paddingTop: 20,
|
||||
}}
|
||||
testID="multiline_textinput_with_flex"
|
||||
multiline={true}
|
||||
placeholder="Placeholder defines intrinsic size"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user