I want to implement show password feature in TextInput in React Native 0.30.0. I've implemented 'eye' button next to TextInput which change state of passwordHidden state variable. Here is my code:
...
<View style={[styles.passwordWrapper, styles.textInputBorder]}>
<TextInput
autoCapitalize={'none'}
autoCorrect={false}
clearButtonMode={'while-editing'}
style={[styles.textInput, styles.passwordInput]}
onChangeText={(password) => this.onPasswordChange(password)}
value={this.state.password}
secureTextEntry={this.state.passwordHidden}
multiline={false}
placeholder={Strings.password}
underlineColorAndroid={Colors.surfacePrimary}
/>
<TouchableOpacity style={styles.showPasswordButton} onPress={this.onPressShowPassword}>
<EntypoIcon color={Colors.surfacePrimary} name={this.state.passwordHidden ? 'eye' : 'eye-with-line'} size={20} />
</TouchableOpacity>
</View>
...
onPressShowPassword: function () {
var previousState = this.state.passwordHidden;
requestAnimationFrame(() => {
this.setState({
passwordHidden: !previousState,
});
});
},
Here's how password TextInput looks before clicking on button.
And after clicking:
And when I tap third time and start type then password is immediately cleared. I am not changing fontFamily in styles even in entire app.
Anybody can explain what is going on? Or just how to overcome that annoying behavior.
Workaround that is working for me, is removing focus from TextInput, when user clicks show/hide password. One way to do this, is to add ref (for example ref="password") to your TextInput and then call this.refs.password.blur()
changing the fontSize works for me:
fontSize: (this.state.showPassword) ? 24 : 23
Related
I am making a comments section for my app with React-Native and building for ios. When the keyboard is up to post a comment I can't immedietley press the TouchableOpacity button that submits the post. I need to first press it to close the keyboard then press again to submit.
const CommentCreation = React.forwardRef((props, ref) => {
return (
<View style={commentCreationStyles.container} >
<TextInput
value={props.message}
ref={ref}
style={commentCreationStyles.input}
onChangeText={val => props.setMessage(val)}
autoFocus={false}
multiline={true}
returnKeyType={'next'}
placeholder={'Enter Your Comment'}
numberOfLines={5}
replyBool={props.replyBool}
/>
<TouchableOpacity
style={commentCreationStyles.submitButton}
onPress={props.addCommentEnabled ? () => {props.addComment(); Keyboard.dismiss()} : null}
>
<Ionicons name="ios-send" size={36} color="#D7D7D7" />
</TouchableOpacity>
</View>
)
})
I have tried keyboardShouldPersistTaps="handled" and its variations in conjunction with ScrollView in addition to View and replacing View. I have tried these on all levels of the tree. I'm at a loss, any help is greatly appreciated!
Add keyboardShouldPersistTaps='handled' in the first View as
<View style={commentCreationStyles.container} keyboardShouldPersistTaps='handled' >
On my TextInput change text, I detect whether the user pushed the # button for mentions.
onChangeText(text){
const suggestTrigger = text.match(/\B#[A-Za-z0-9]*$/i) //grab "#" trigger
const searchQuery = (suggestTrigger && suggestTrigger.length > 0) ? suggestTrigger[0] : null;
this.setState({
searchQuery: searchQuery
})
}
Then, in my render, I do:
<TextInput
autoCapitalize={this.state.searchQuery ? "none" : "sentences"}
autoCorrect={this.state.searchQuery ? false : true}
onChangeText={this.onChangeText}
/>
However, even when I do this, the autoCorrect does not turn off.
I still see this:
This is causing problems because oftentimes the system replaces the entire mention with a different word altogether.
How can I turn autoCorrect and autoCapitalize off when the user pushes the # button?
'
I have even tried rendering an entirely different , but the behavior remains.
TL;DR: you should close and re-launch your keyboard after the TextInput autoCorrect toggling value.
Buddy, this is not your fault, I had the same issue on autoFocus of react native TextInput component. I set a state name for the TextInput editable prop and then with the pressing pencil button I change the editable props. The designer told me after the TextInput made editable the cursor should be focused, so I use the isEditable state for autoFocus prop, see below:
state = {
isEditable: false
};
handleEdit = () => {
const { isEditable } = this.state;
this.setState({ isEditable: !isEditable });
};
<TextInput
autoFocus={isEditable}
editable={isEditable}
style={styles.textNameEditable}
defaultValue={text}
numberOfLines={1}
/>
Then I press the edit button and it turns to:
But it is not focused and the Keyboard didn't launch, I sought and found this link, the TextInput does not change/update some of its props after componentDidMount. ☹️. Also, it is not different in iOS or Android, both of them has this issue, I used ref to focus on this TextInput after the isEditable state made true. see following code:
<TextInput
editable={isEditable}
style={styles.textNameEditable}
defaultValue={text}
numberOfLines={1}
ref={input => {
this.input = input;
}}
/>
componentDidUpdate() {
const { isEditable } = this.state;
if (isEditable) {
this.input.focus();
}
}
And your case:
Absolutely you can not use ref because the autoCorrect should render with react native and it is not like focus() and blur() so JavaScript cannot access to it.
I make a test shape for your case, I create another button like a star for toggling autoCorrect value alongside my edit button. the filled star means autoCorrect is true and the lined star means autoCorrect is false, now see the test area code and view:
state = {
isEditable: false,
correct: true
};
handleCorrect = () => {
const { correct } = this.state;
this.setState({ correct: !correct });
};
<TextInput
autoCorrect={correct}
editable={isEditable}
style={styles.textNameEditable}
defaultValue={text}
numberOfLines={1}
ref={input => {
this.input = input;
}}
/>
In the above photo, it is so clear the autoCorrect rendered as true, so it is enabled:
When I write a wrong Persian word the auto-correction show its suggestion, now time to press the star button:
Wow, the autoCorrection is false in the above situation but still we see the auto-correction of the cellphone. it is just like autoFocus it is rendered in the first render and after it, the TextInput could not change/update its props. suddenly I press edit button:
And I press the edit button again, so surely, you realized the autoCorrect is false now, ok now see what I saw:
The autoCorrect remained false by my double pressing edit button and now the auto-correction of device disappears completely. I don't know it is a bug or my bad understanding but I realized in this test area, for update autoCorrect value, we should do something after changing its value to close the iPhone keyboard and then re-launch it. the main thing that TextInput has issued is the launched keyboard.
For my test, when I pressed the edit button the editable prop of the TextInput is changed to false and the keyboard is closed, so when I pressed the edit button again, the TextInput get focused and keyboard re-launched with new autoCorrect value. This is The Secret.
Solution:
You should do something, to close and open again the iOS keyboard with the new autoCorrect value. for the test case that I wrote for your question, I decided to do a hybrid innovative solution, using ref and the callback of setState:
handleCorrect = () => {
const { correct } = this.state;
this.input.blur(); //-- this line close the keyboard
this.setState({ correct: !correct },
() => {
setTimeout(() => this.input.focus(), 50);
//-- above line re-launch keyboard after 50 milliseconds
//-- this 50 milliseconds is for waiting to closing keyborad finish
}
);
};
<TextInput
autoCorrect={correct}
editable={isEditable}
style={styles.textNameEditable}
defaultValue={text}
numberOfLines={1}
ref={input => {
this.input = input;
}}
/>
And after pressing the star button the keyboard close and re-launch and the auto-correction disappear completely.
Note: obviously, I summarized some other codes like destructuring and writing class or extends and etc for better human readability.
The problem isn't in your code completely(except Regex part which didn't work in my device) but how the React Native renders Keyboard.
I created a sample that along with your initial code also changes backgroundColor of the screen.
You will find that color changes instantly when '#' is entered whereas the keyboard doesn't.
Unless you reload the keyboard. For this, if you un-comment the code it dismisses keyboard once and once you tap back on textInput the new Keyboard without autoCorrect and autoCapitalize is shown.
state = {
searchQuery: null,
isFocused: true,
}
constructor(props) {
super(props);
this.onChangeText = this.onChangeText.bind(this);
}
onChangeText = (val) => {
const suggestTrigger = val.match(/#[A-Za-z0-9]*$/i) //grab "#" trigger
const searchQuery = (suggestTrigger && suggestTrigger.length > 0) ? suggestTrigger[0] : null;
// Un comment this to reload
// if(searchQuery && this.state.isFocused) {
// this.setState({
// isFocused: false
// });
// Keyboard.dismiss();
// // this.myTextInput.focus()
// }
this.setState({
searchQuery: searchQuery
})
}
render() {
const { searchQuery } = this.state
return (
<View style={[styles.container,
{
backgroundColor: searchQuery ? "red": "green"}
]}>
<TextInput
style={{width: 300, height: 50, borderWidth: 1}}
ref={(ref)=>{this.myTextInput = ref}}
autoCapitalize={searchQuery ? "none" : "sentences"}
autoCorrect={searchQuery ? false : true}
onChangeText={this.onChangeText}
/>
</View>
);
}
Since now we know the main cause of error may be a better solution can be reached.
I have 2 suggestions:
First, have you tried using the autoCorrect fallback?
spellCheck={this.state.searchQuery ? false : true}
Second, have you tried with native code (Obj-C / Swift)?
import { Platform, TextInput, View } from 'react-native';
import { iOSAutoCorrect } from './your-native-code';
const shouldWork = Platform.OS === 'ios' ? <iOSAutoCorrect /> : <TextInput
autoCapitalize={this.state.searchQuery ? "none" : "sentences"}
autoCorrect={this.state.searchQuery ? false : true}
onChangeText={this.onChangeText} />
return (<View>{shouldWork}</View>);
In iOSAutoCorrect you should use a UITextView. Then set its proper value depending on your condition:
textField.autocorrectionType = UITextAutocorrectionTypeNo; // or UITextAutocorrectionTypeYes
I have free-coded, thus the code is untested and might contain bugs.
I have a TextInput inside a ScrollView.
The scroll isn't working when the TextInput is on focus. This problem is only affecting Android.
setting
<ScrollView keyboardShouldPersistTaps="always"
in combination with the textInput component below (custom component that i created for text inputs to solve this issue) solved my problem:
<TouchableOpacity
activeOpacity={1}
onPress={()=>this.input.focus()}>
<View pointerEvents="none"
<TextInput
ref = {(input) => this.input = input}
/>
</View>
</TouchableOpacity>
In scrollView use keyboardShouldPersistTaps
<ScrollView keyboardShouldPersistTaps="handled">
it solve your problem
check docs here https://facebook.github.io/react-native/docs/scrollview.html#keyboarddismissmode
That is the expected behavior.
For more information Official TextInput documentation
You might want to try something like this: react-native-kayboard-aware-scroll-view
i use simple trick for TextInput and that work for me correctly .Should add this prop in TextInput :
<TextInput
multiline={true}
numberOfLines={1}
/>
This is a very good example: http://blog.arjun.io/react-native/mobile/cross-platform/2016/04/01/handling-the-keyboard-in-react-native.html
The thing that was really important for me was to add:
android:windowSoftInputMode="adjustResize"
in AndroidManifest.xml in order to focus the textInput
I handle in different ways to each platform (in Ios focus to inputText is enough,
don't forget to put this.scrollViewRef ref inside ScrollView that wrap inputText and put ref index the inputText
if (Platform.OS == 'android') {
this.inputRefs[field].measure((w, h, px, py, xPage, yPage) => {
this.scrollViewRef.scrollTo({ x: 0, y: yPage, animated: true })
this.inputRefs[field].focus()
})
}
this.inputRefs[field].focus()
I have this issue in both iOS Simulator and in real device too.
I have a Listview with Touchablehighlight. When i press the list at first, it ignores. It only functions when it is double clicked.Can anyone help me out with this.
Here i have a piece of code, that is inside my render function
<ListView dataSource= {ds.cloneWithRows(this.state.searchedAdresses)}
renderRow={this.renderAdress}
renderSeparator={this._renderSeperator}
enableEmptySections={true}
automaticallyAdjustContentInsets={false}
/>
renderAdress = (rowData, sectionID, rowID) => {
return (
<TouchableHighlight onPress = {this._onPressAddressList.bind(this,rowData.place_id,rowData.description)}underlayColor = '#a9a9a9' >
<View shouldRasterizeIOS={true} renderToHardwareTextureAndroid={true}>
<Text style={ styles.listTextInput } >{rowData.description</Text>
</View>
</TouchableHighlight>
);};
Thank you
I can think of 2 cases:
You have TextInput gaining the focus and when you tap your list view item the first time it removes focus from the input and hides the keyboard. This is described here.
They reported that this is an issue with emulator.
I am using listView with TextInputs, on ios when TextInput focused it's behind keyboard. How to fix it?
Sample code: http://rnplay.org/apps/8baZSA
You need to use <ScrollView> instead of <View> in order to use this method.
The key method is scrollResponderScrollNativeHandleToKeyboard(refToElement, scrollHeight, preventNegativeOffset) (sounds cool, right ;))
I have:
<TextInput ref='ccName' onFocus={(() => this.onFieldFocus('ccName'))} />
where function looks like:
onFieldFocus(fieldName) {
this.setTimeout(() => {
let scrollResponder = this.refs.scrollView.getScrollResponder()
scrollResponder.scrollResponderScrollNativeHandleToKeyboard(
React.findNodeHandle(this.refs[fieldName]), 200, true
)
}, 125)
}
Seems this thread is what you're looking for.
TL;DR: see this stackoverflow question