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

[iOS] Fix TextInput maxLength when insert characters at begin #23472

Closed
wants to merge 3 commits into from

Conversation

zhongwuzw
Copy link
Contributor

Summary

Fixes #21639 , seems we tried to fix this before, please see related PR like D10392176, #18627, but they don't solve it totally.

Changelog

[iOS] [Fixed] - Fix TextInput maxLength when insert characters at begin

Test Plan

From the git log, we faced some issues, like Backspace event, we need to ensure no regression happened, issues like #21639 #18627 should be fixed.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Feb 15, 2019
@react-native-bot react-native-bot added Component: TextInput Related to the TextInput component. Platform: iOS iOS applications. PR: Includes Changelog labels Feb 15, 2019
@cpojer cpojer requested a review from shergin February 15, 2019 10:37
@shergin
Copy link
Contributor

shergin commented Feb 15, 2019

@rigdern Adam, what do you think?

@rigdern
Copy link
Contributor

rigdern commented Feb 15, 2019

@shergin I'm not familiar with this code. I read over the PR but it's unclear to me what flaw in the code is causing the symptom and why this delta fixes it.

@zhongwuzw
Copy link
Contributor Author

@shergin @rigdern Thanks for review, my opinion is _predictedText should always equal to the combination of backedTextInputView's original text and replaced text. The original if..else.. check may leads to inconformity between _predictedText and backedTextInputView's text.

@zhongwuzw
Copy link
Contributor Author

@shergin @cpojer Hi, any opinion?

@ejanzer
Copy link

ejanzer commented Mar 5, 2019

@zhongwuzw Can you share that the issue is you're seeing and how to repro it? Like @rigdern said, it's not clear to me what the issue is and how this fixes it - if you're seeing an inconsistency here, then it seems like predictedText already got out of sync with the backing textinput view. I think this change may make sense regardless, but I just want to take a look and see where things are going wrong.

@zhongwuzw
Copy link
Contributor Author

@ejanzer Hi, I borrowed the repro from #21639 :

Description

[iOS only]

When entering 1 character at the beginning of the TextInput, we expect to have only 1 character inserted. However we experience that the character is inserted and the current value is duplicated.

This behaviour is reproducible when the prop maxLength is used and when length of the current value is above the half of the maxLength prop.

I have created an app from scratch using create-react-native-app, and I have modified App.js to include the following:

type Props = {};
export default class App extends Component<Props> {
  constructor(props) {
    super(props);
    this.state = { text: '10000' };
  }

  render() {
    return (
      <View style={styles.container}>
        <TextInput
          style={{height: 40, width:120, borderColor: 'gray', borderWidth: 1}}
          maxLength={10}
          onChangeText={(text) => this.setState({text})}
          value={this.state.text}/>
      </View>
    );
  }
}

Reproducible Demo

demo

@zhongwuzw
Copy link
Contributor Author

Based on repro example, when we insert 0 at the begin, the _predictedText should equal to 0 10000, but the old code, it equal to 0, leads to the issue.

@ejanzer
Copy link

ejanzer commented Mar 6, 2019

Oh I see, the problem is if you set an initial value from JS then _predictedText never gets properly initialized, so it's nil when you get here. We could also fix this by explicitly checking if it's nil, but I think this change makes sense - from the code it looks like _predictedText is supposed to be used to detect when the backing textinput updated without textInputShouldChangeTextInRange getting called.

@zhongwuzw would you mind also cleaning up the other places in this file where we set _predictedText, since they're no longer needed?

Copy link

@ejanzer ejanzer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment about previousText - also please clean up the other places where we set _predictedText if they're no longer needed:

if (range.location + range.length > _predictedText.length) {

and

_predictedText = backedTextInputView.attributedText.string;

@@ -338,11 +338,7 @@ - (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSStrin

NSString *previousText = [_predictedText substringWithRange:range] ?: @"";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably move this above here so that previousText is set correctly.

@zhongwuzw
Copy link
Contributor Author

@ejanzer Hey, I clean up the code, please continue to review it.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ejanzer has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ejanzer has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@react-native-bot
Copy link
Collaborator

This pull request was successfully merged by @zhongwuzw in 1741593.

When will my fix make it into a release? | Upcoming Releases

@react-native-bot react-native-bot added the Merged This PR has been merged. label Mar 12, 2019
kelset pushed a commit that referenced this pull request Mar 29, 2019
Summary:
Fixes #21639 , seems we tried to fix this before, please see related `PR` like [D10392176](36507e4), #18627, but they don't solve it totally.

[iOS] [Fixed] - Fix TextInput maxLength when insert characters at begin
Pull Request resolved: #23472

Reviewed By: mmmulani

Differential Revision: D14366406

Pulled By: ejanzer

fbshipit-source-id: fc983810703997b48824f84f2f9198984afba9cd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Component: TextInput Related to the TextInput component. Merged This PR has been merged. Platform: iOS iOS applications.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

TextInput duplicate value when inserting at the beginning (ios) maxLength
6 participants