How do I enable touch on multiple buttons simultaneously in react native?
Asked Answered
L

4

10

I need that when I am touching and holding one button then I should also be able to touch on the button 1.

<View>
  
  <View 
  onStartShouldSetResponder={()=>this.console("Button 2 Clicked")}>
    <Text>BUTTON 2</Text>
  </View>
  
  <TouchableOpacity 
  onPressIn={()=>this.console('Button 1 pressed')}
  onPressOut={()=>this.console('Button 1 released')}>
    <View>
      <Text>BUTTON 1</Text>
    </View>
  </TouchableOpacity>

</View>

Basically, I have a screen where I can record a video by tapping and holding the record button(Button 1). On the same screen, I have a flip camera button (Button 2). I want that I should be able to click on the flip camera button while I am recording the video.

Langbehn answered 14/3, 2017 at 1:53 Comment(1)
Did you ever end up figuring out how to do this??Nullifidian
L
2

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>
Langbehn answered 14/3, 2017 at 7:5 Comment(2)
This does not work for the multi touch if you set a Boolean value when both buttons are pressed it will always remain either (true false) or (false true) seems they just cancel each other out. I am going to try use pan responder to see if i can get it to work with that. facebook.github.io/react-native/docs/panresponder.htmlSiemens
Unfortunately this only seems work on iOS and not AndroidHumus
H
1

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>
        );
    }
}
Humus answered 21/8, 2017 at 7:8 Comment(1)
I gave this a try, The element within onTouchStart is always logged as the first button one that is touched. i added a props left and right to each button and logged it, If i hold the right button then tap the left right is always logged.Siemens
P
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

Placer answered 10/5, 2020 at 10:7 Comment(0)
C
1

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.

Corinecorinna answered 26/10, 2020 at 8:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.