Как включить одновременное касание нескольких кнопок в React Native?

Мне нужно, чтобы, когда я касаюсь и удерживаю одну кнопку, я также мог коснуться кнопки 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>

По сути, у меня есть экран, на котором я могу записывать видео, нажав и удерживая кнопку записи (кнопка 1). На этом же экране у меня есть кнопка флип-камеры (кнопка 2). Я хочу, чтобы у меня была возможность нажать кнопку флип-камеры во время записи видео.


person Satya P. Goyal    schedule 14.03.2017    source источник
comment
Вы когда-нибудь выясняли, как это сделать ??   -  person Perniferous    schedule 27.04.2021


Ответы (4)


Эту проблему можно легко решить с помощью реквизитов onTouchStart, onTouchEnd компонента View без использования методов ответа на жесты.

Таким образом, измененный код будет выглядеть так

<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>
person Satya P. Goyal    schedule 14.03.2017
comment
Это не работает для мультитач, если вы устанавливаете логическое значение, когда обе кнопки нажаты, оно всегда будет оставаться либо (true false), либо (false true), кажется, что они просто компенсируют друг друга. Я собираюсь попробовать использовать Pan Responder, чтобы посмотреть, смогу ли я заставить его работать с этим. facebook.github.io/react-native/docs/panresponder.html - person Aidan Doherty; 16.06.2017
comment
К сожалению, это работает только на iOS, а не на Android. - person FOLOF; 04.07.2019

Это мое решение для нескольких кнопок

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>
        );
    }
}

Затем я просто оборачиваю кнопки, которые нужно нажимать одновременно с компонентом

<MultiTouch style={this.style.view}>
    <UpDownButton />
    <UpDownButton />
</MultiTouch>

Ваше здоровье!

ОБНОВЛЕНИЕ

Из-за критических изменений в нативной реакции v.0.51 мое предыдущее решение больше не работает. Но мне удается создать новый. Вместо использования TouchableWithoutFeedback и onPress я использую View и onTouch для каждой кнопки, которая должна иметь мультитач.

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>
        );
    }
}
person FOLOF    schedule 21.08.2017
comment
Я попробовал это. Элемент в onTouchStart всегда регистрируется как первая кнопка, к которой прикоснулись. Я добавил реквизиты влево и вправо для каждой кнопки и зарегистрировал их. Если я удерживаю правую кнопку, то касание левой и правой всегда регистрируется. - person Aidan Doherty; 28.08.2017

Я использовал реактивный обработчик жестов. Установите его и просто замените

import { TouchableOpacity } from 'react-native';

с участием

import { TouchableOpacity } from 'react-native-gesture-handler';

Пример

<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>

Ссылка: https://software-mansion.github.io/react-native-gesture-handler/docs/component-touchables.html

Эта библиотека также предлагает компоненты кнопок, которые можно использовать напрямую вместо переноса текста с помощью TouchableOpacity.

person Ganesh Sundar C    schedule 10.05.2020

Пытаться:

import { TouchableOpacity } from 'react-native';

Вместо:

import { TouchableOpacity } from 'react-native-gesture-handler';

Поможет вам несколько кнопок.

Например, если у вас есть TouchableOpacity внутри TouchableWithoutFeedback, когда TouchableOpacity is touched, он будет вызывать только onPress TouchableOpacity и не будет вызываться onPress TouchableWithoutFeedback.

person Doan Bui    schedule 26.10.2020