react-native
react-native copied to clipboard
TextInput > iOS > selectTextOnFocus not working as expected
Description
I created a fresh project using the npx react-native@latest init textinputBug
and added a simple text input.
<TextInput
value="test"
style={{marginBottom: 20, backgroundColor: 'grey', padding: 10}}
selectTextOnFocus
/>
Noticed 2 weird behaviors on iOS. I tested on both iOS 16.4
and 17.2
.
- The first issue is that if you press on any words of a
non-focused
text input, the text will be selected on the16.4
but not on the17.2
. - The second issue is that if you press on the text input area that doesn't have any text, the text will not be selected on either of the devices. I'm unsure if this is a bug or a default behavior of text inputs on iOS. (the same action selects the whole text on Android)
Please watch the video for more information and let me know if you need more info
Steps to reproduce
- Initialized a fresh project using
npx react-native@latest init textinputBug
- Added a text input with the mentioned props
- Noticed weird behaviors
React Native Version
0.73.1
Affected Platforms
Runtime - iOS
Output of npx react-native info
System:
OS: macOS 14.2
CPU: (8) arm64 Apple M1 Pro
Memory: 105.28 MB / 16.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 18.18.0
path: ~/.nvm/versions/node/v18.18.0/bin/node
Yarn:
version: 1.22.19
path: /usr/local/bin/yarn
npm:
version: 9.8.1
path: ~/.nvm/versions/node/v18.18.0/bin/npm
Watchman:
version: 2023.09.04.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.13.0
path: /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 23.2
- iOS 17.2
- macOS 14.2
- tvOS 17.2
- watchOS 10.2
Android SDK:
API Levels:
- "27"
- "28"
- "29"
- "30"
- "31"
- "33"
- "33"
- "34"
Build Tools:
- 30.0.3
- 33.0.0
- 33.0.1
- 33.0.2
- 34.0.0
System Images:
- android-28 | Google ARM64-V8a Play ARM 64 v8a
- android-33 | Google APIs ARM 64 v8a
- android-34 | Google Play ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2022.3 AI-223.8836.35.2231.10406996
Xcode:
version: 15.1/15C65
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.8.1
path: /usr/bin/javac
Ruby:
version: 2.6.10
path: /usr/bin/ruby
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 18.2.0
wanted: 18.2.0
react-native:
installed: 0.73.1
wanted: 0.73.1
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: false
iOS:
hermesEnabled: true
newArchEnabled: false
Stacktrace or Logs
There's not runtime error. It's a UI bug
Reproducer
https://github.com/AlirezaHadjar/textinputBug
Screenshots and Videos
https://github.com/facebook/react-native/assets/57192409/acbb404f-573c-4292-85b8-8ea049118fcd
Related to this issue: https://github.com/facebook/react-native/issues/30585
This is still a bug, selectTextOnFocus
does not work for me either on iOS as expected (I'm on react-native 0.72.6).
A working temporary solution is found here: https://github.com/facebook/react-native/issues/30585#issuecomment-1330928411 (thanks @pascallapointe)
<TextInput
value={value}
onFocus={e =>
// Workaround for selectTextOnFocus={true} not working
e.currentTarget.setNativeProps({
selection: { start: 0, end: value?.toString().length },
});
}
...
/>
Setting multiline
to true also works, but this does not fit my use-case since then returnKeyType='done'
enters a new line instead of toggling the keyboard.
I'm also having this issue and it seems to work intermittently in no predictable way
Happening for me too.
Happening to me too. I managed to fix it by also including the selection
prop, seems they are linked in some way, while not being explained in the documentation?
Happening to me too. I managed to fix it by also including the
selection
prop, seems they are linked in some way, while not being explained in the documentation?
This option works, but is not very good from a UX point of view, because the text will be highlighted every time (also when editing).
My temporal suggestion it's using ref for set selection on focus.
const ref = useRef(null)
const [value, setValue] = useState('');
const onFocus = () => {
input.current?.setSelection(0, value.length);
}
return <TextInput value={value} onChangeText={setValue} ref={ref} onFocus={onFocus} />
I'm hitting this too. I think it's a bug. Does anyone have a burning desire to dig into the source code and figure out what's going on?
I briefly investigated this and seem to have found the cause of the problem and a potential fix. Opened a PR here. Hopefully if it isn't the right fix it at least points in the right direction for someone to pick it up (especially since it also affects Fabric!) https://github.com/facebook/react-native/pull/44307
Right now, the underlying native code selects the text like so in non-fabric:
- (void)textInputDidBeginEditing
{
// Removed some other code for clarity
if (_selectTextOnFocus) {
[self.backedTextInputView selectAll:nil];
}
[_eventDispatcher sendTextEventWithType:RCTTextEventTypeFocus
reactTag:self.reactTag
text:[self.backedTextInputView.attributedText.string copy]
key:nil
eventCount:_nativeEventCount];
}
This seems logical at first glance, and it actually is highlighting the text. Notice that we briefly sometimes see the selection before losing it.
https://github.com/facebook/react-native/assets/153161762/b18c4235-5a7f-49af-9321-835d553d15ab
A bit more investigation reveals that the method reactFocus
is later called, always after textInputDidBeginEditing
. Whenever reactFocus
gets called, we lose the selection. If we move the selectAll
call to after reactFocus
, then we consistently see the expected behavior.
https://github.com/bluesky-social/social-app/assets/153161762/b6a2c7fb-958f-4376-b634-35a935f0764e
Hopefully if this isn't the appropriate fix it at least gives someone the right idea of where to go looking.