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

TextInput with TextAlign on iOS does not add ellipsis instead wraps #29068

Open
msaqlain opened this issue Jun 5, 2020 · 29 comments
Open

TextInput with TextAlign on iOS does not add ellipsis instead wraps #29068

msaqlain opened this issue Jun 5, 2020 · 29 comments
Labels
Component: TextInput Related to the TextInput component. Needs: Attention Issues where the author has responded to feedback. Needs: Environment Info Please run `react-native info` and edit your issue with that command's output. Platform: iOS iOS applications.

Comments

@msaqlain
Copy link

msaqlain commented Jun 5, 2020

import React, { PureComponent } from 'react';
import {Text, TextInput, View} from 'react-native';

const App = () => {
  return (
    <View style={{flex: 1, justifyContent: 'center'}}>
      <View>
        <Text>Text Input without alignment</Text>
        <TextInput style={{padding: 10, margin: 20, borderColor: 'grey', borderWidth: 1}}/>
        <Text>Text Input with right alignment</Text>
        <TextInput textAlign={'right'} style={{padding: 10, margin: 20, borderColor:  'grey', borderWidth: 1}}/>
      </View>
      <TextInput/>
    </View>);
};

export default App;

Write some long text into the first field with spaces.
image

Write similar text into the second field.
image

Unfocus second input
Expected: both fields will have ellipsis at the end
Actual: second input with textAlign doesn't have ellipsis.

Android app works in a different way:
It never shows ellipsis but if you type a long string it always shows the end of it and never beginning. I guess it should move to begin when unfocused.

react: 16.11.0 => 16.11.0
react-native: 0.62.1 => 0.62.1

@react-native-bot react-native-bot added Component: TextInput Related to the TextInput component. Platform: iOS iOS applications. Needs: Author Feedback Needs: Environment Info Please run `react-native info` and edit your issue with that command's output. and removed Needs: Triage 🔍 labels Jun 5, 2020
@github-actions
Copy link

github-actions bot commented Jun 5, 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.

@msaqlain
Copy link
Author

msaqlain commented Jul 6, 2020

Any Update? Its been 1 month now.

@github-actions github-actions bot added Needs: Attention Issues where the author has responded to feedback. and removed Needs: Author Feedback labels Jul 6, 2020
@msaqlain
Copy link
Author

Comment. Just to keep this thread active.

@cameronbell
Copy link

I am also seeing this issue on "react-native": "0.61.5"

@xanderdeseyn
Copy link

Same on 0.63.3

@JNUfeatherwit
Copy link

Any Solution?

@shreypdev
Copy link

@JNUfeatherwit Adding VerticalPadding through CSS solves the issue of multiline but still no ellipsis.

@JNUfeatherwit
Copy link

@JNUfeatherwit Adding VerticalPadding through CSS solves the issue of multiline but still no ellipsis.

Wow! It Actually works! Thank you

@kokiebisu
Copy link

This issue is still persisting. Adding the verticalPadding does not ultimately solve the problem. Any updates?

@TomSwift
Copy link
Contributor

TomSwift commented Dec 3, 2021

@JNUfeatherwit can you elaborate on your vertical padding solution? There is no "CSS" in react-native so that is confusing to me. Applying vertical padding in the style for a TextInput isn't changing any of the wrapping behavior for us.

Having investigated, I believe the issue is in the RCTUITextField (which backs the single-line TextInput component) implementation itself. Text content is being set to the underlying UITextField using attributedText. Attributed text strings in iOS have a default paragraph style that permits wrapping. I was able to patch RCTUITextField with the following to change the default paragraph style to truncate, and this works. We're going to run with this patch for a while to see if it's a good fix, but would love to have additional feedback on this as a solution.

In RCTUITextField.m:

- (void)setDefaultTextAttributes:(NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes
{    
  if ([_defaultTextAttributes isEqualToDictionary:defaultTextAttributes]) {
    return;
  }

  // limit single-line fields to 1-line (no wrapping)
  if ([self.textInputDelegate isKindOfClass: [RCTSinglelineTextInputView class]]) {
      NSParagraphStyle* ps = defaultTextAttributes[NSParagraphStyleAttributeName];
      NSMutableParagraphStyle* mps = [ps mutableCopy];
      mps.lineBreakMode = NSLineBreakByTruncatingTail;
      NSMutableDictionary<NSAttributedStringKey, id>* mutableDefaultTextAttributes = [defaultTextAttributes mutableCopy];
      mutableDefaultTextAttributes[NSParagraphStyleAttributeName] = [mps copy];
      defaultTextAttributes = [mutableDefaultTextAttributes copy];
  }
    
  _defaultTextAttributes = defaultTextAttributes;
  [super setDefaultTextAttributes:defaultTextAttributes];
  [self _updatePlaceholder];
}

@mohamedanwer123
Copy link

any updates ?
any solution ?

@osmyn
Copy link

osmyn commented Mar 11, 2022

This is the workaround mentioned above:

StyleSheet.create({
 textInput: {
  ...Platform.select({
      ios: {
        paddingVertical: 0.001, // fix line wrap issue
      },
      android: {},
    }),
 }
});

@thiagobutignon
Copy link

Any updates?

@tiagomsmagalhaes
Copy link

Just found out this bug, because I'm using react-native-paper and due to this callstack/react-native-paper#2684 issue and was able to find a solution inside the downstream issue

Shame that this issue is now 2 years old, and to me it seems critical to be resolved as beginners could stumble on this and get their frustration level rising

@GameraCC
Copy link

To clarify, adding a slight vertical padding to the TextInput element does not always work, you've got to experiment and figure out what works without overflowing the text input.

Solution below:

const styles = new StyleSheet.create({
    textInput: {
        ...(Platform.OS === 'ios' ? {paddingVertical: 10} : {})
    }
})
const Element = () => <TextInput style={styles.textInput}>

@riledv
Copy link

riledv commented Aug 26, 2022

Oh... crap It needs to be fixed

@frenberg
Copy link

@JNUfeatherwit can you elaborate on your vertical padding solution? There is no "CSS" in react-native so that is confusing to me. Applying vertical padding in the style for a TextInput isn't changing any of the wrapping behavior for us.

Having investigated, I believe the issue is in the RCTUITextField (which backs the single-line TextInput component) implementation itself. Text content is being set to the underlying UITextField using attributedText. Attributed text strings in iOS have a default paragraph style that permits wrapping. I was able to patch RCTUITextField with the following to change the default paragraph style to truncate, and this works. We're going to run with this patch for a while to see if it's a good fix, but would love to have additional feedback on this as a solution.

In RCTUITextField.m:

- (void)setDefaultTextAttributes:(NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes
{    
  if ([_defaultTextAttributes isEqualToDictionary:defaultTextAttributes]) {
    return;
  }

  // limit single-line fields to 1-line (no wrapping)
  if ([self.textInputDelegate isKindOfClass: [RCTSinglelineTextInputView class]]) {
      NSParagraphStyle* ps = defaultTextAttributes[NSParagraphStyleAttributeName];
      NSMutableParagraphStyle* mps = [ps mutableCopy];
      mps.lineBreakMode = NSLineBreakByTruncatingTail;
      NSMutableDictionary<NSAttributedStringKey, id>* mutableDefaultTextAttributes = [defaultTextAttributes mutableCopy];
      mutableDefaultTextAttributes[NSParagraphStyleAttributeName] = [mps copy];
      defaultTextAttributes = [mutableDefaultTextAttributes copy];
  }
    
  _defaultTextAttributes = defaultTextAttributes;
  [super setDefaultTextAttributes:defaultTextAttributes];
  [self _updatePlaceholder];
}

Hey @TomSwift are you still using this patch or did you find any problems with it?

@projectnatz
Copy link

Issue still open in react-native 0.70.6 😢

@mikekreeki
Copy link

Still an issue.

@yourjhay
Copy link

Sometimes textAlign works, sometimes not.

@fabOnReact
Copy link
Contributor

Hello,

Thanks for the issue. I have been contributing to facebook/react-native for 4 years and specialize in the Text/TextInput components. I currently have 58 facebook/react-native PRs:

https://github.com/facebook/react-native/pulls?q=is%3Apr+author%3Afabriziobertoglio1987+

This is the suggested approach from the react-native core team (see this discussion):

I'm publishing several fixes for Text and TextInput component in a separate library react-native-improved.

  • The Component is based on ReactTextView, it is the same implementation from react-native.
  • It will include several bug fixes.
  • You can use the library until the PR is merged and released with react-native.
  • You can use side by side both components from react-native and react-native-improved, depending on where you need the fix.
  • I will also publish the PR to facebook/react-native (daily fixes and releases).

The advantages would be:

  • Increased engagement with the community, issues are quickly fixed.
  • No limitations when merging PRs (react-native main branch is used on facebook marketplace).
  • Only Meta employees can merge and review facebook/react-native PRs.
  • Allows us to further experiment and develop react-native.

What do you think about this? Should I keep working on this? Thanks

@sieeniu
Copy link

sieeniu commented Mar 25, 2024

any updates?

@seanmaisch
Copy link

Would like to see this resolved as well. It's quite pesky that even with multiline={false} there is text that is able to wrap to the next line if a TextInput is not focused.

@MateuszBukowski93
Copy link

Still doesn't work.

fix for me:
Fixed height

@TomasSestak
Copy link

would be nice to have this working

@thiagobutignon
Copy link

Almost 4 years without a solution!

@tibbe
Copy link

tibbe commented May 2, 2024

This seems like a very core issue. Basic inputs like a text field is something I think everyone would expect to work in its basic form (i.e. just input long text).

@ilight
Copy link

ilight commented May 9, 2024

@JNUfeatherwit can you elaborate on your vertical padding solution? There is no "CSS" in react-native so that is confusing to me. Applying vertical padding in the style for a TextInput isn't changing any of the wrapping behavior for us.

Having investigated, I believe the issue is in the RCTUITextField (which backs the single-line TextInput component) implementation itself. Text content is being set to the underlying UITextField using attributedText. Attributed text strings in iOS have a default paragraph style that permits wrapping. I was able to patch RCTUITextField with the following to change the default paragraph style to truncate, and this works. We're going to run with this patch for a while to see if it's a good fix, but would love to have additional feedback on this as a solution.

In RCTUITextField.m:

- (void)setDefaultTextAttributes:(NSDictionary<NSAttributedStringKey, id> *)defaultTextAttributes
{    
  if ([_defaultTextAttributes isEqualToDictionary:defaultTextAttributes]) {
    return;
  }

  // limit single-line fields to 1-line (no wrapping)
  if ([self.textInputDelegate isKindOfClass: [RCTSinglelineTextInputView class]]) {
      NSParagraphStyle* ps = defaultTextAttributes[NSParagraphStyleAttributeName];
      NSMutableParagraphStyle* mps = [ps mutableCopy];
      mps.lineBreakMode = NSLineBreakByTruncatingTail;
      NSMutableDictionary<NSAttributedStringKey, id>* mutableDefaultTextAttributes = [defaultTextAttributes mutableCopy];
      mutableDefaultTextAttributes[NSParagraphStyleAttributeName] = [mps copy];
      defaultTextAttributes = [mutableDefaultTextAttributes copy];
  }
    
  _defaultTextAttributes = defaultTextAttributes;
  [super setDefaultTextAttributes:defaultTextAttributes];
  [self _updatePlaceholder];
}

This worked for me, thank you @TomSwift

@shubhamguptadream11
Copy link
Collaborator

This is going to be fixed here: #45968
Basically now you need to use a prop lineBreakModeIOS with break strategy you want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component: TextInput Related to the TextInput component. Needs: Attention Issues where the author has responded to feedback. Needs: Environment Info Please run `react-native info` and edit your issue with that command's output. Platform: iOS iOS applications.
Projects
None yet
Development

No branches or pull requests