react-native: Problem with TextInput lineHeight on iOS
Hi, guys! Did someone facing the same issue with lineHeight on iOS ? any solution ?
React Native version: “0.61.5”
Android:
iOS:
Code:
import React from 'react'
import { View, TextInput, StyleSheet } from 'react-native'
export default function Example () {
return (
<View style={styles.wrapper}>
<TextInput style={styles.input} placeholder='Hello World!' />
</View>
)
}
const styles = StyleSheet.create({
wrapper: {
height: '100%',
width: '100%',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'lightgray'
},
input: {
height: 32,
minWidth: 120,
lineHeight: 32,
borderWidth: 1,
backgroundColor: 'white',
padding: 0,
fontSize: 14
}
})
same on 0.62.2 version
rn info:
System:
OS: macOS 10.15.5
CPU: (8) x64 Intel(R) Core(TM) i7-4770HQ CPU @ 2.20GHz
Memory: 404.19 MB / 16.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 14.2.0 - ~/.nvm/versions/node/v14.2.0/bin/node
Yarn: 1.17.3 - /usr/local/bin/yarn
npm: 6.14.4 - ~/.nvm/versions/node/v14.2.0/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.9.1 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 13.5, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
Android SDK: Not Found
IDEs:
Android Studio: 3.6 AI-192.7142.36.36.6241897
Xcode: 11.5/11E608c - /usr/bin/xcodebuild
Languages:
Java: 13.0.2 - /usr/bin/javac
Python: 2.7.16 - /usr/bin/python
npmPackages:
@react-native-community/cli: Not Found
react: ^16.13.1 => 16.13.1
react-native: 0.62.2 => 0.62.2
npmGlobalPackages:
*react-native*: Not Found
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 19
- Comments: 20 (4 by maintainers)
Commits related to this issue
- reduce cursor size for multiline(TextInput) (#36484) Summary: Currently in multiline input the cursor touches the previous line. So this reduces its height sets its position so that I does not touch ... — committed to rozele/react-native-macos by soumyajit4419 a year ago
- fix: make cursor center for different line height (#36586) Summary: Currently in multiline input the cursor touches the previous line. So this reduces its height sets its position so that I does not ... — committed to rozele/react-native-macos by soumyajit4419 a year ago
- reduce cursor size for multiline(TextInput) (#36484) Summary: Currently in multiline input the cursor touches the previous line. So this reduces its height sets its position so that I does not touch ... — committed to jeongshin/react-native by soumyajit4419 a year ago
- fix: make cursor center for different line height (#36586) Summary: Currently in multiline input the cursor touches the previous line. So this reduces its height sets its position so that I does not ... — committed to jeongshin/react-native by soumyajit4419 a year ago
- reduce cursor size for multiline(TextInput) (#36484) Summary: Currently in multiline input the cursor touches the previous line. So this reduces its height sets its position so that I does not touch ... — committed to OlimpiaZurek/react-native by soumyajit4419 a year ago
- fix: make cursor center for different line height (#36586) Summary: Currently in multiline input the cursor touches the previous line. So this reduces its height sets its position so that I does not ... — committed to OlimpiaZurek/react-native by soumyajit4419 a year ago
- Fix TextInput vertical alignment issue when using lineHeight prop on iOS without changing Text baseline (Paper - old arch) (#38359) Summary: This PR fixes visual regression introduced with https://gi... — committed to facebook/react-native by fabOnReact 5 months ago
- Fix TextInput vertical alignment issue when using lineHeight prop on iOS without changing Text baseline (Paper - old arch) (#38359) Summary: This PR fixes visual regression introduced with https://gi... — committed to facebook/react-native by fabOnReact 5 months ago
Is there a workaround for this? still happening in RN
v0.72.3
Example from Issue https://github.com/facebook/react-native/issues/28012
Text is not correctly aligned when using lineHeight and height in a TextInput.
Before applying the fix
<video src="https://user-images.githubusercontent.com/24992535/235421165-e1553caf-ef32-4223-8ffb-13aee320953f.mp4" width="200" />
After applying the fix
<video src="https://user-images.githubusercontent.com/24992535/235421377-23bbee11-adde-40de-9ded-a293f4010bbb.mp4 " width="200" />
https://user-images.githubusercontent.com/24992535/235421238-302c1cd6-806a-491d-9321-eeb03815a9b5.mp4
For the past few years I’ve just avoided using
lineHeight
on React Native, as it’s more trouble than it’s worth. However, while you can add padding to a single line there’s no decent hack for multiline text. Hopefully there’s a solution soon.@askel4dd That doesn’t seem to fix the issue.
It seems that the problem only happens on iOS with large
fontSize
-lineHeight
differences. (In the original examplefontSize: 14
andlineHeight: 32
.) The workaround for me right now is to setlineHeight: null
and use a wrapperView
to achieve correct positioning.Please re-state the problem that we are trying to solve in this issue.
What is the root cause of that problem?
The issue is caused by adding lineHeight to TextInput (Issue https://github.com/facebook/react-native/issues/28012).
What changes do you think we should make in order to solve the problem?
Fix react-native TextInput (iOS) font metrics (descent) to avoid cutting text when setting the lineHeight ( https://stackoverflow.com/a/27631737/7295772).
The issue only reproduces with TextInput, but not with Text, while both manage text style using the same API RCTAttributedTextUtils.
The text is cut when setting the lineHeight prop. The TextInput component sets the lineHeight without adjusting the baseline of the text with RCTBaselineOffset (RCTAttributedTextUtils#RCTNSTextAttributesFromTextAttributes). Text and TextInput component use shared API AttributedText to style the Text in the TextInput, but TextInput currently misses this logic (RCTApplyBaselineOffset). It was tested with this video (https://github.com/Expensify/App/issues/17767#issuecomment-1526631224) in the Expensify App. Changing RCTApplyBaselineOffset does not change the baseline of the AttributedText in the TextInput, but changes the baseline of the appended Text.
As we can see the Text is cut if lineHeight is lower then Text height (image)
Commenting the code and the Text is not cut (image)
It is caused by the missing implementation in the TextInput of RCTBaselineOffset, which correctly sets the Text baseline and avoids cutting the text
RCTTextInputComponentView generates the text with RCTNSTextAttributesFromTextAttributes instead of RCTNSAttributedStringFromAttributedString
RCTBaselineOffset changes the text baseline (see the above screenshots and https://github.com/Expensify/App/issues/17767#issuecomment-1526631224) and avoids this regression with Text component, but it is not implemented for TextInput component.
Summary: