I need that when I am touching and holding one button then I should also be able to touch on the button 1.
I used react-native-gesture-handler. Install it and just replace
import { TouchableOpacity } from 'react-native';
with
import { TouchableOpacity } from 'react-native-gesture-handler';
Example
<View>
<TouchableOpacity
onPressIn={()=>this.console('Button 2 pressed')}
onPressOut={()=>this.console('Button 2 released')}>
<View>
<Text>BUTTON 2</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
onPressIn={()=>this.console('Button 1 pressed')}
onPressOut={()=>this.console('Button 1 released')}>
<View>
<Text>BUTTON 1</Text>
</View>
</TouchableOpacity>
</View>
Link: https://software-mansion.github.io/react-native-gesture-handler/docs/component-touchables.html
This library also offers button components which can be directly used instead of wrapping Text with TouchableOpacity
Try:
import { TouchableOpacity } from 'react-native';
Instead of:
import { TouchableOpacity } from 'react-native-gesture-handler';
Will help you to multiple buttons.
For example, if you have a TouchableOpacity
inside a TouchableWithoutFeedback
, when TouchableOpacity is touched
, it will only call TouchableOpacity's onPress, and will not be called onPress of TouchableWithoutFeedback
.
This is my solution for multiple buttons
import React, { Component } from 'react';
import {
View,
PanResponder,
} from 'react-native';
import ReactNativeComponentTree from'react-native/Libraries/Renderer/shims/ReactNativeComponentTree';
export default class MultiTouch extends Component{
constructor(props) {
super(props);
this.onTouchStart = this.onTouchStart.bind(this);
this.onTouchEnd = this.onTouchEnd.bind(this);
this.onTouchCancel = this.onTouchCancel.bind(this);
this.triggerEvent = this.triggerEvent.bind(this);
}
onTouchStart(event){
const element = ReactNativeComponentTree.getInstanceFromNode(event.target)._currentElement;
this.triggerEvent(element._owner, 'onPressIn');
}
onTouchEnd(event){
const element = ReactNativeComponentTree.getInstanceFromNode(event.target)._currentElement;
this.triggerEvent(element._owner, 'onPressOut');
}
onTouchCancel(event){
const element = ReactNativeComponentTree.getInstanceFromNode(event.target)._currentElement;
this.triggerEvent(element._owner, 'onPressOut');
}
onTouchMove(event){
// console.log(event);
}
triggerEvent(owner, event){ // Searching down the
if(!owner || !owner.hasOwnProperty('_instance')){
return;
}
if(owner._instance.hasOwnProperty(event)){
owner._instance[event]();
}else{
this.triggerEvent(owner._currentElement._owner, event);
}
}
render(){
return (
<View
onTouchStart={this.onTouchStart}
onTouchEnd={this.onTouchEnd}
onTouchCancel={this.onTouchCancel}
onTouchMove={this.onTouchMove}>
{this.props.children}
</View>
);
}
}
Then I simply wrap the buttons that needs to be pressed at the same time withe the component
<MultiTouch style={this.style.view}>
<UpDownButton />
<UpDownButton />
</MultiTouch>
Cheers!
UPDATE
Because of breaking changes in native react v.0.51, my previous solution does not work any more. But I manage to create a new one. Instead of using TouchableWithoutFeedback and onPress I use View and onTouch on each button that should have multitouch.
import React, { Component } from 'react';
import {
View,
} from 'react-native';
export default class RoundButtonPart extends Component{
constructor(props) {
super(props);
this.state = { active: false };
this.onTouchStart = this.onTouchStart.bind(this);
this.onTouchEnd = this.onTouchEnd.bind(this);
this.onTouchCancel = this.onTouchCancel.bind(this);
}
onTouchStart(event){
this.setState({ active: true });
this.props.onPressIn && this.props.onPressIn();
}
onTouchEnd(event){
this.setState({ active: false });
this.props.onPressOut && this.props.onPressOut();
}
onTouchCancel(event){
this.setState({ active: false });
this.props.onPressOut && this.props.onPressOut();
}
onTouchMove(event){
}
render(){
return (
<View
onTouchStart={this.onTouchStart}
onTouchEnd={this.onTouchEnd}
onTouchCancel={this.onTouchCancel}
onTouchMove={this.onTouchMove}>
{this.props.children}
</View>
);
}
}
This problem can easily be resolved using onTouchStart, onTouchEnd props of View component without using gesture responder methods.
So the modified code will look like
<View>
<View onTouchStart={()=>this.console("Button 2 Clicked")}>
<Text>BUTTON 2</Text>
</View>
<View
onTouchStart={()=>this.console('Button 1 pressed')}
onTouchEnd={()=>this.console('Button 1 released')}>
<Text>BUTTON 1</Text>
</View>
</View>