Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with TextInput lineHeight on iOS #28012

Closed
tohellandback opened this issue Feb 10, 2020 · 20 comments
Closed

Problem with TextInput lineHeight on iOS #28012

tohellandback opened this issue Feb 10, 2020 · 20 comments
Assignees

Comments

@tohellandback
Copy link

tohellandback commented Feb 10, 2020

Hi, guys! Did someone facing the same issue with lineHeight on iOS ? any solution ?

React Native version: "0.61.5"

Android:
Screenshot 2020-02-10 at 16 21 04

iOS:
Screenshot 2020-02-10 at 16 21 13

Screenshot 2020-06-03 at 20 23 56

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
@chrisglein chrisglein added the Needs: Environment Info Please run `react-native info` and edit your issue with that command's output. label Apr 1, 2020
@label-actions
Copy link

label-actions bot commented Apr 1, 2020

⚠️ Missing Environment Information
ℹ️ Your issue may be missing information about your development environment. You can obtain the missing information by running react-native info in a console.

@react-native-bot react-native-bot removed the Needs: Environment Info Please run `react-native info` and edit your issue with that command's output. label Apr 1, 2020
@mikelros
Copy link

Same here. Hope it's fixed soon 👍

@konstantin-shkel
Copy link

konstantin-shkel commented Apr 26, 2020

same on 0.62.2

rn info

System:
OS: macOS 10.15.4
CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz
Memory: 102.72 MB / 16.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 12.15.0 - /usr/local/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.13.4 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
Managers:
CocoaPods: 1.8.4 - /usr/local/bin/pod
SDKs:
iOS SDK:
Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1
Android SDK: Not Found
IDEs:
Android Studio: 3.5 AI-191.8026.42.35.6010548
Xcode: 11.2.1/11B53 - /usr/bin/xcodebuild
Languages:
Java: 10.0.2 - /usr/bin/javac
Python: 2.7.15 - /usr/local/bin/python
npmPackages:
@react-native-community/cli: Not Found
react: 16.11.0 => 16.11.0
react-native: 0.62.2 => 0.62.2
npmGlobalPackages:
react-native: Not Found

@Esxiel
Copy link

Esxiel commented Jul 13, 2020

Here to confirm that the problem persists in 0.63.0 as well

@stale
Copy link

stale bot commented Oct 12, 2020

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as a "Discussion" or add it to the "Backlog" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Oct 12, 2020
@askel4dd
Copy link

askel4dd commented Dec 1, 2020

Applied changes from #29262 using patch-package to fix this, like so:

diff --git a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m
index 6603554..e87e0d0 100644
--- a/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m
+++ b/node_modules/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m
@@ -96,6 +96,11 @@ - (void)invalidateContentSize
     maximumSize.height = CGFLOAT_MAX;
   }

+  maximumSize.width -= self.paddingLeft.value + self.paddingRight.value;
+  maximumSize.width -= self.borderWidth;
+  maximumSize.height -= self.paddingTop.value + self.paddingBottom.value;
+  maximumSize.height -= self.borderWidth;
+
   CGSize contentSize = [self sizeThatFitsMinimumSize:(CGSize)CGSizeZero maximumSize:maximumSize];

   if (CGSizeEqualToSize(_previousContentSize, contentSize)) {

React Native 0.63.3

@stale stale bot removed the Stale There has been a lack of activity on this issue and it may be closed soon. label Dec 1, 2020
@saskaak
Copy link

saskaak commented May 4, 2021

@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 example fontSize: 14 and lineHeight: 32.) The workaround for me right now is to set lineHeight: null and use a wrapper View to achieve correct positioning.

@dann1609
Copy link

the issue is still present.

@filiptdz
Copy link

filiptdz commented Sep 2, 2022

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.

@Akronae
Copy link

Akronae commented Feb 7, 2023

Same boat here

@kelset kelset added the Type: Unsupported Version Issues reported to a version of React Native that is no longer supported label Feb 9, 2023
@github-actions
Copy link

github-actions bot commented Feb 9, 2023

It looks like your issue or the example you provided uses an unsupported version of React Native. Due to the amount of issues we receive, we're currently accepting only new issues against one of the supported version. Please open your issue on StackOverflow to get further community support.

@Akronae
Copy link

Akronae commented Feb 15, 2023

same on 0.62.2

rn info

System: OS: macOS 10.15.4 CPU: (4) x64 Intel(R) Core(TM) i5-5257U CPU @ 2.70GHz Memory: 102.72 MB / 16.00 GB Shell: 5.7.1 - /bin/zsh Binaries: Node: 12.15.0 - /usr/local/bin/node Yarn: 1.22.4 - /usr/local/bin/yarn npm: 6.13.4 - /usr/local/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman Managers: CocoaPods: 1.8.4 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 13.2, DriverKit 19.0, macOS 10.15, tvOS 13.2, watchOS 6.1 Android SDK: Not Found IDEs: Android Studio: 3.5 AI-191.8026.42.35.6010548 Xcode: 11.2.1/11B53 - /usr/bin/xcodebuild Languages: Java: 10.0.2 - /usr/bin/javac Python: 2.7.15 - /usr/local/bin/python npmPackages: @react-native-community/cli: Not Found react: 16.11.0 => 16.11.0 react-native: 0.62.2 => 0.62.2 npmGlobalPackages: react-native: Not Found

The author seems not to be active anymore, however plenty have provided some versions, and I would say that this happens on any version..

@github-actions
Copy link

This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days.

@github-actions github-actions bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Mar 11, 2023
@github-actions
Copy link

This issue was closed because the author hasn't provided the requested feedback after 7 days.

@fabOnReact fabOnReact reopened this Apr 27, 2023
@fabOnReact
Copy link
Contributor

fabOnReact commented Apr 27, 2023

I corrected the formatting. The issue environment infos were hidden in comments. I just had to add the closing tags ``` for the code example.

@fabOnReact
Copy link
Contributor

fabOnReact commented Apr 28, 2023

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 #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).

  1. react-native TextInput is just a wrapper around the iOS API UITextField
  2. the TextInput text is styled with NSAttributedString

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 (Expensify/App#17767 (comment)) 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 Expensify/App#17767 (comment)) and avoids this regression with Text component, but it is not implemented for TextInput component.

Summary:

  • The string is not cut while using Text component.
  • Text and TextInput components use the same API to style the text (AttributedString).
  • The Text component applies custom logic when applying setting the lineHeight (RCTBaselineOffset). The logic modifies the text fontMetrics and avoids cutting the text.
  • There is a missing implementation of RCTBaselineOffset in TextInput, which causes the regression (the text has the wrong baseline and it is cut).

@fabOnReact
Copy link
Contributor

@fabOnReact fabOnReact self-assigned this Apr 30, 2023
@fabOnReact fabOnReact removed Stale There has been a lack of activity on this issue and it may be closed soon. Needs: Triage 🔍 Needs: Author Feedback Type: Unsupported Version Issues reported to a version of React Native that is no longer supported labels Apr 30, 2023
@facebook facebook unlocked this conversation Apr 30, 2023
@fabOnReact
Copy link
Contributor

Example from Issue #28012

Text is not correctly aligned when using lineHeight and height in a TextInput.

Before applying the fix

main.branch.mp4

After applying the fix

correct.caret.position.mp4

correct.caret.position.2.mp4

rozele pushed a commit to rozele/react-native-macos that referenced this issue May 1, 2023
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 previous line.
This PR will also fix the issue facebook#28012 (Problem with TextInput lineHeight on iOS)
## Changelog

[IOS] [ADDED] - Fixed cursor height on multiline text input
<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

Pull Request resolved: facebook#36484

Test Plan:
UI Before the change
<img width="379" alt="Screenshot 2023-03-15 at 10 16 07 PM" src="https://user-images.githubusercontent.com/46092576/225380938-23b9b8a4-4b8a-45e1-bbf1-4af8ac8d9183.png">

UI After the change
<img width="509" alt="Screenshot 2023-03-14 at 1 57 27 AM" src="https://user-images.githubusercontent.com/46092576/225380930-77ca853c-fae5-4bfa-82cf-03b2e22bf8da.png">

Reviewed By: dmytrorykun

Differential Revision: D44130814

Pulled By: javache

fbshipit-source-id: 09d53ecee6812e9a875dc5364bd91b76cc2bc1f5
rozele pushed a commit to rozele/react-native-macos that referenced this issue May 1, 2023
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 previous line.
This PR will also fix the issue facebook#28012 (Problem with TextInput lineHeight on iOS)
This RP will fix the issue caused in
[PR](facebook#36484)

Changelog:
[iOS][Added] - Fixed cursor height on multiline text input

Pull Request resolved: facebook#36586

Test Plan:
Tested for different cursor height

https://user-images.githubusercontent.com/46092576/227004355-3886a0b5-7cdb-4fdc-a16b-3c4abb729737.mov

https://user-images.githubusercontent.com/46092576/227004361-48099f81-9f52-460d-8ae8-d0ddb09dc47d.mov

Reviewed By: javache

Differential Revision: D44307457

Pulled By: genkikondo

fbshipit-source-id: afeea5605ed8557cdeec1e62324c85665ce367d6
jeongshin pushed a commit to jeongshin/react-native that referenced this issue May 7, 2023
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 previous line.
This PR will also fix the issue facebook#28012 (Problem with TextInput lineHeight on iOS)
## Changelog

[IOS] [ADDED] - Fixed cursor height on multiline text input
<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

Pull Request resolved: facebook#36484

Test Plan:
UI Before the change
<img width="379" alt="Screenshot 2023-03-15 at 10 16 07 PM" src="https://user-images.githubusercontent.com/46092576/225380938-23b9b8a4-4b8a-45e1-bbf1-4af8ac8d9183.png">

UI After the change
<img width="509" alt="Screenshot 2023-03-14 at 1 57 27 AM" src="https://user-images.githubusercontent.com/46092576/225380930-77ca853c-fae5-4bfa-82cf-03b2e22bf8da.png">

Reviewed By: dmytrorykun

Differential Revision: D44130814

Pulled By: javache

fbshipit-source-id: 09d53ecee6812e9a875dc5364bd91b76cc2bc1f5
jeongshin pushed a commit to jeongshin/react-native that referenced this issue May 7, 2023
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 previous line.
This PR will also fix the issue facebook#28012 (Problem with TextInput lineHeight on iOS)
This RP will fix the issue caused in
[PR](facebook#36484)

Changelog:
[iOS][Added] - Fixed cursor height on multiline text input

Pull Request resolved: facebook#36586

Test Plan:
Tested for different cursor height

https://user-images.githubusercontent.com/46092576/227004355-3886a0b5-7cdb-4fdc-a16b-3c4abb729737.mov

https://user-images.githubusercontent.com/46092576/227004361-48099f81-9f52-460d-8ae8-d0ddb09dc47d.mov

Reviewed By: javache

Differential Revision: D44307457

Pulled By: genkikondo

fbshipit-source-id: afeea5605ed8557cdeec1e62324c85665ce367d6
OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this issue May 22, 2023
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 previous line.
This PR will also fix the issue facebook#28012 (Problem with TextInput lineHeight on iOS)
## Changelog

[IOS] [ADDED] - Fixed cursor height on multiline text input
<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests
-->

Pull Request resolved: facebook#36484

Test Plan:
UI Before the change
<img width="379" alt="Screenshot 2023-03-15 at 10 16 07 PM" src="https://user-images.githubusercontent.com/46092576/225380938-23b9b8a4-4b8a-45e1-bbf1-4af8ac8d9183.png">

UI After the change
<img width="509" alt="Screenshot 2023-03-14 at 1 57 27 AM" src="https://user-images.githubusercontent.com/46092576/225380930-77ca853c-fae5-4bfa-82cf-03b2e22bf8da.png">

Reviewed By: dmytrorykun

Differential Revision: D44130814

Pulled By: javache

fbshipit-source-id: 09d53ecee6812e9a875dc5364bd91b76cc2bc1f5
OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this issue May 22, 2023
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 previous line.
This PR will also fix the issue facebook#28012 (Problem with TextInput lineHeight on iOS)
This RP will fix the issue caused in
[PR](facebook#36484)

Changelog:
[iOS][Added] - Fixed cursor height on multiline text input

Pull Request resolved: facebook#36586

Test Plan:
Tested for different cursor height

https://user-images.githubusercontent.com/46092576/227004355-3886a0b5-7cdb-4fdc-a16b-3c4abb729737.mov

https://user-images.githubusercontent.com/46092576/227004361-48099f81-9f52-460d-8ae8-d0ddb09dc47d.mov

Reviewed By: javache

Differential Revision: D44307457

Pulled By: genkikondo

fbshipit-source-id: afeea5605ed8557cdeec1e62324c85665ce367d6
@bryanprimus
Copy link

Is there a workaround for this? still happening in RN v0.72.3

@kimjson
Copy link

kimjson commented Dec 28, 2023

@bryanltobing you can try applying this fix using patch-package

facebook-github-bot pushed a commit that referenced this issue Feb 2, 2024
…iOS without changing Text baseline (Paper - old arch) (#38359)

Summary:
This PR fixes visual regression introduced with #37465 (comment)

Adding paragraphStyle.maximumLineHeight to a iOS UITextField displays the text under the UITextField ([ios-screenshot-1][1], [ios-screenshot-2][2], [ios-screenshot-3][3]).

The PR implements the logic from RCTTextShadowView [#postprocessAttributedText](https://github.com/facebook/react-native/blob/9ab27e8895d6934e72ebdc601d169578ab9628f1/packages/react-native/Libraries/Text/Text/RCTTextShadowView.m#L165-L167) in RCTBaseTextInpuShadowView [#uiManagerWillPerformMounting](https://github.com/facebook/react-native/blob/4c944540f732c6055d447ecaf37d5c8f3eec1bc4/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m#L130-L192).

[1]: https://user-images.githubusercontent.com/24992535/238834159-566f7eef-ea2d-4fd4-a519-099b0a12046c.png "ios-screenshot-1"
[2]: https://user-images.githubusercontent.com/24992535/238834184-feb454a9-6504-4832-aec8-989f1d027861.png "ios-screenshot-2"
[3]: https://user-images.githubusercontent.com/24992535/238834283-cf572f94-a641-4790-92bf-bbe43afb1443.png "ios-screenshot-3"

[4]: https://github.com/Expensify/App/assets/24992535/06726b45-7e35-4003-9fcc-50c8d0dff0f6
[5]: https://github.com/Expensify/App/assets/24992535/d9745d29-8863-4170-bcc3-e78fa7e550d2

fixes #28012 fixes #33986
Related #35741 #31112

## Changelog:

[IOS] [FIXED] - Fix TextInput vertical alignment issue when using lineHeight prop on iOS without changing Text baseline (Paper - old arch)

Pull Request resolved: #38359

Test Plan: Extensive test included in the PR comments #37465 (comment) and Expensify/App#17767 (comment)

Reviewed By: cipolleschi

Differential Revision: D52325261

Pulled By: dmytrorykun

fbshipit-source-id: d072a598bfaafbbffc41005b1fda1795cf3d8ab9
lunaleaps pushed a commit that referenced this issue Feb 20, 2024
…iOS without changing Text baseline (Paper - old arch) (#38359)

Summary:
This PR fixes visual regression introduced with #37465 (comment)

Adding paragraphStyle.maximumLineHeight to a iOS UITextField displays the text under the UITextField ([ios-screenshot-1][1], [ios-screenshot-2][2], [ios-screenshot-3][3]).

The PR implements the logic from RCTTextShadowView [#postprocessAttributedText](https://github.com/facebook/react-native/blob/9ab27e8895d6934e72ebdc601d169578ab9628f1/packages/react-native/Libraries/Text/Text/RCTTextShadowView.m#L165-L167) in RCTBaseTextInpuShadowView [#uiManagerWillPerformMounting](https://github.com/facebook/react-native/blob/4c944540f732c6055d447ecaf37d5c8f3eec1bc4/packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.m#L130-L192).

[1]: https://user-images.githubusercontent.com/24992535/238834159-566f7eef-ea2d-4fd4-a519-099b0a12046c.png "ios-screenshot-1"
[2]: https://user-images.githubusercontent.com/24992535/238834184-feb454a9-6504-4832-aec8-989f1d027861.png "ios-screenshot-2"
[3]: https://user-images.githubusercontent.com/24992535/238834283-cf572f94-a641-4790-92bf-bbe43afb1443.png "ios-screenshot-3"

[4]: https://github.com/Expensify/App/assets/24992535/06726b45-7e35-4003-9fcc-50c8d0dff0f6
[5]: https://github.com/Expensify/App/assets/24992535/d9745d29-8863-4170-bcc3-e78fa7e550d2

fixes #28012 fixes #33986
Related #35741 #31112

## Changelog:

[IOS] [FIXED] - Fix TextInput vertical alignment issue when using lineHeight prop on iOS without changing Text baseline (Paper - old arch)

Pull Request resolved: #38359

Test Plan: Extensive test included in the PR comments #37465 (comment) and Expensify/App#17767 (comment)

Reviewed By: cipolleschi

Differential Revision: D52325261

Pulled By: dmytrorykun

fbshipit-source-id: d072a598bfaafbbffc41005b1fda1795cf3d8ab9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment