Skip to content

Instantly share code, notes, and snippets.

@MikeShi42
Created October 19, 2016 20:36
Show Gist options
  • Save MikeShi42/87b65984f0a31e38d553cc056fcda017 to your computer and use it in GitHub Desktop.
Save MikeShi42/87b65984f0a31e38d553cc056fcda017 to your computer and use it in GitHub Desktop.
Terrible TextInput extends that doesn't steal all touches.
import React, { Component } from 'react';
import {TextInput, TouchableWithoutFeedback, StyleSheet} from 'react-native';
const Platform = require('Platform');
const requireNativeComponent = require('requireNativeComponent');
const emptyFunction = require('fbjs/lib/emptyFunction');
if (Platform.OS === 'android') {
var AndroidTextInput = requireNativeComponent('AndroidTextInput', null);
} else if (Platform.OS === 'ios') {
var RCTTextView = requireNativeComponent('RCTTextView', null);
var RCTTextField = requireNativeComponent('RCTTextField', null);
}
const onlyMultiline = {
onTextInput: true,
children: true,
};
class SlideTextInput extends TextInput {
constructor() {
super();
this._renderIOS = this._renderIOSWithoutEventSteal;
}
_renderIOSWithoutEventSteal() {
var textContainer;
var onSelectionChange;
if (this.props.selectionState || this.props.onSelectionChange) {
onSelectionChange = (event: Event) => {
if (this.props.selectionState) {
var selection = event.nativeEvent.selection;
this.props.selectionState.update(selection.start, selection.end);
}
this.props.onSelectionChange && this.props.onSelectionChange(event);
};
}
var props = Object.assign({}, this.props);
props.style = [styles.input, this.props.style];
if (!props.multiline) {
if (__DEV__) {
for (var propKey in onlyMultiline) {
if (props[propKey]) {
const error = new Error(
'TextInput prop `' + propKey + '` is only supported with multiline.'
);
warning(false, '%s', error.stack);
}
}
}
textContainer =
<RCTTextField
ref="input"
{...props}
onFocus={this._onFocus}
onBlur={this._onBlur}
onChange={this._onChange}
onSelectionChange={onSelectionChange}
onSelectionChangeShouldSetResponder={emptyFunction.thatReturnsTrue}
text={this._getText()}
/>;
} else {
var children = props.children;
var childCount = 0;
ReactChildren.forEach(children, () => ++childCount);
invariant(
!(props.value && childCount),
'Cannot specify both value and children.'
);
if (childCount >= 1) {
children = <Text style={props.style}>{children}</Text>;
}
if (props.inputView) {
children = [children, props.inputView];
}
textContainer =
<RCTTextView
ref="input"
{...props}
children={children}
onFocus={this._onFocus}
onBlur={this._onBlur}
onChange={this._onChange}
onContentSizeChange={this.props.onContentSizeChange}
onSelectionChange={onSelectionChange}
onTextInput={this._onTextInput}
onSelectionChangeShouldSetResponder={emptyFunction.thatReturnsTrue}
text={this._getText()}
/>;
}
return (
<TouchableWithoutFeedback
onLayout={props.onLayout}
onPress={this._onPress}
rejectResponderTermination={false}
accessible={props.accessible}
accessibilityLabel={props.accessibilityLabel}
accessibilityTraits={props.accessibilityTraits}
testID={props.testID}>
{textContainer}
</TouchableWithoutFeedback>
);
}
}
var styles = StyleSheet.create({
input: {
alignSelf: 'stretch',
},
});
export default SlideTextInput;
@adamski
Copy link

adamski commented Nov 11, 2016

This is great! I'm using it with https://github.com/jemise111/react-native-swipe-list-view and it works well.
Some comments on what changes you made would be super useful.
I'd like to get it working on Android too. I'll let you know how I get on.

Thanks!

@MikeShi42
Copy link
Author

@adamski Sorry for the late response, didn't get a notif. In case you were still curious, there's a full write up of this gist, with references to the RN source of how/why this is being done:

https://medium.com/@mikeshi/react-native-swipeouts-textinputs-animations-and-gesture-responders-a6baa4745735

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment