Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript PanResponder中的滚动视图_Javascript_Ios_React Native_Tabs_Uiscrollview - Fatal编程技术网

Javascript PanResponder中的滚动视图

Javascript PanResponder中的滚动视图,javascript,ios,react-native,tabs,uiscrollview,Javascript,Ios,React Native,Tabs,Uiscrollview,我正在通过在React Native中滑动来实现我自己的选项卡导航器。它工作得很好,但当我的一个标签中有一个滚动视图时,它似乎坏了。向左和向右滑动以更改选项卡工作正常,并且在scrollview中向下和向上滚动。当我单击拖动scrollView,然后侧移而不释放以进行滑动时,它会断开。然后选项卡系统将重置为第一个选项卡 我做了一个黑客,当滚动视图时,我禁用从选项卡内部滑动。这是可行的,但感觉像是一个糟糕的解决方案,因为选项卡内容必须知道它在选项卡中 import React, { Compone

我正在通过在React Native中滑动来实现我自己的选项卡导航器。它工作得很好,但当我的一个标签中有一个滚动视图时,它似乎坏了。向左和向右滑动以更改选项卡工作正常,并且在scrollview中向下和向上滚动。当我单击拖动scrollView,然后侧移而不释放以进行滑动时,它会断开。然后选项卡系统将重置为第一个选项卡

我做了一个黑客,当滚动视图时,我禁用从选项卡内部滑动。这是可行的,但感觉像是一个糟糕的解决方案,因为选项卡内容必须知道它在选项卡中

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { View, Animated, Dimensions, PanResponder } from 'react-native';
import Immutable from 'immutable';
import Tab1 from './Tab1';
import Tab2 from './Tab2';
import ScrollViewTab from './ScrollViewTab';


@connect(
    state => ({
        tabs: state.tabs
    })
)

export default class Tabs extends Component {
    static propTypes = {
        tabs: PropTypes.instanceOf(Immutable.Map).isRequired,
        dispatch: PropTypes.func.isRequired
    };
    constructor(props) {
        super(props);
        this.justLoaded = true;
        this.state = {
            left: new Animated.Value(0),
            tabs: [{ // Tabs must be in order, despite index.
                name: 'tab1',
                component: <Tab1 setTab={this.setTab} />,
                index: 0
            }, {
                name: 'tab2',
                component: <Tab2 setTab={this.setTab} />,
                index: 1
            }, {
                name: 'scrollViewTab',
                component: <ScrollViewTab setTab={this.setTab} />,
                index: 2
            }]
        };
        this.getIndex = this.getIndex.bind(this);
    }
    componentWillMount() {
        this.panResponder = PanResponder.create({
            onMoveShouldSetResponderCapture: () => true,
            onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
                if (Math.abs(gestureState.dx) > 10) {
                    return true;
                }
                return false;
            },
            onPanResponderGrant: () => {
                this.state.left.setOffset(this.state.left._value);
                this.state.left.setValue(0);
            },
            onPanResponderMove: (e, gestureState) => {
                if (this.isSwipingOverLeftBorder(gestureState) ||
                    this.isSwipingOverRightBorder(gestureState)) return;
                Animated.event([null, {
                    dx: this.state.left
                }])(e, gestureState);
            },
            onPanResponderRelease: (e, gestureState) => {
                this.state.left.flattenOffset();

                if (this.isSwipingOverLeftBorder(gestureState) ||
                    this.isSwipingOverRightBorder(gestureState)) {
                    return;
                }

                Animated.timing(
                    this.state.left,
                    { toValue: this.calcX(gestureState) }
                ).start();
            }
        });
    }
    componentDidMount() {
        this.justLoaded = false;
    }
    getStyle() {
        const oldLeft = this.state.left;
        let left = 0;
        const screenWidth = Dimensions.get('window').width;
        // Set tab carouselle coordinate to match the selected tab.
        this.state.tabs.forEach((tab) => {
            if (tab.name === this.props.tabs.get('tab')) {
                left = -tab.index * screenWidth;
            }
        });


        if (this.justLoaded) {
            Animated.timing(
                this.state.left,
                { toValue: left,
                    duration: 0
                }
            ).start();

            return { transform: [{ translateX: oldLeft }], flexDirection: 'row', height: '100%' };
        }
        Animated.timing(
                this.state.left,
            { toValue: left
            }
            ).start();
        return { transform: [{ translateX: oldLeft }], flexDirection: 'row', height: '100%' };
    }
    getIndex(tabN) {
        let index = 0;

        this.state.tabs.forEach((tab) => {
            if (tab.name === tabN) {
                index = tab.index;
            }
            return tab;
        });

        return index;
    }
    setTab(tab, props) {
        this.navProps = props;
        this.props.dispatch({ type: 'SET_TAB', tab });
    }
    isSwipingOverLeftBorder(gestureState) {
        return (this.props.tabs.get('tab') === this.state.tabs[0].name &&
                gestureState.dx > 0);
    }
    isSwipingOverRightBorder(gestureState) {
        return (this.props.tabs.get('tab') === this.state.tabs[this.state.tabs.length - 1].name &&
                gestureState.dx < 0);
    }
    calcX(gestureState) {
        const screenWidth = Dimensions.get('window').width;
        const activeTab = this.getIndex(this.props.tabs.get('tab'));
        let coord = 0;

        if (gestureState.dx > screenWidth * 0.2) {
            coord = (activeTab * screenWidth) - screenWidth;
        } else if (gestureState.dx < -(screenWidth * 0.2)) {
            coord = (activeTab * screenWidth) + screenWidth;
        } else {
            coord = activeTab * screenWidth;
        }

        this.updateTab(-coord, screenWidth);

        return -coord;
    }
    updateTab(coord, screenWidth) {
        // Update current tab according to location and screenwidth
        this.state.tabs.forEach((tab) => {
            if (coord === -tab.index * screenWidth) {
                this.props.dispatch({ type: 'SET_TAB', tab: tab.name });
            }
        });
    }
    render() {
        return (
          <View
            style={{ flex: 1 }}
          >
            <Animated.View
              style={this.getStyle()}
              {...this.panResponder.panHandlers}
            >
              {this.state.tabs.map(tab => tab.component)}
            </Animated.View>
          </View>
        );
    }
}
import React,{Component,PropTypes}来自'React';
从'react redux'导入{connect};
从“react native”导入{视图、动画、维度、PanResponder};
从“不可变”导入不可变;
从“/Tab1”导入Tab1;
从“/Tab2”导入Tab2;
从“/ScrollViewTab”导入ScrollViewTab;
@连接(
状态=>({
选项卡:state.tabs
})
)
导出默认类选项卡扩展组件{
静态类型={
选项卡:PropTypes.instanceOf(Immutable.Map).isRequired,
调度:需要PropTypes.func.isRequired
};
建造师(道具){
超级(道具);
this.justLoaded=true;
此.state={
左:新动画。值(0),
制表符:[{//制表符必须有序,不管索引如何。
名称:'tab1',
组成部分:,
索引:0
}, {
名称:'tab2',
组成部分:,
索引:1
}, {
名称:'scrollViewTab',
组成部分:,
索引:2
}]
};
this.getIndex=this.getIndex.bind(this);
}
组件willmount(){
this.panResponder=panResponder.create({
onMoveShouldSetResponderCapture:()=>true,
onMoveShouldSetPanResponderCapture:(evt,手势状态)=>{
if(Math.abs(gestureState.dx)>10){
返回true;
}
返回false;
},
onPanResponderGrant:()=>{
this.state.left.setOffset(this.state.left.\u值);
此.state.left.setValue(0);
},
onPanResponderMove:(e,手势状态)=>{
if(this.isSwipingOverLeftBorder(gestureState)||
此.isSwipingOverRightBorder(gestureState))返回;
已设置动画的.event([null{
dx:这个。州。左
}])(e)手势状态;
},
onPanResponderRelease:(e,手势状态)=>{
this.state.left.flattOffset();
if(this.isSwipingOverLeftBorder(gestureState)||
此.IsWipingOverRightBorder(gestureState)){
返回;
}
时间(
这个州,左,
{toValue:this.calcX(gestureState)}
).start();
}
});
}
componentDidMount(){
this.justLoaded=false;
}
getStyle(){
const oldlift=this.state.left;
设左=0;
const screenWidth=Dimensions.get('window').width;
//将制表符转盘坐标设置为与所选制表符匹配。
this.state.tabs.forEach((tab)=>{
if(tab.name==this.props.tabs.get('tab')){
左=-tab.index*屏幕宽度;
}
});
如果(此.justLoaded){
时间(
这个州,左,
{toValue:left,
持续时间:0
}
).start();
返回{transform:[{translateX:oldLeft}],flexDirection:'row',height:'100%};
}
时间(
这个州,左,
{toValue:左
}
).start();
返回{transform:[{translateX:oldLeft}],flexDirection:'row',height:'100%};
}
getIndex(tabN){
设指数=0;
this.state.tabs.forEach((tab)=>{
如果(tab.name==tabN){
索引=tab.index;
}
返回选项卡;
});
收益指数;
}
设置选项卡(选项卡,道具){
this.navProps=props;
this.props.dispatch({type:'SET_TAB',TAB});
}
isSwipingOverLeftBorder(gestureState){
return(this.props.tabs.get('tab')==this.state.tabs[0]。name&&
gestureState.dx>0);
}
isSwipingOverRightBorder(手势状态){
return(this.props.tabs.get('tab')==this.state.tabs[this.state.tabs.length-1].name&&
gestureState.dx<0);
}
calcX(手势状态){
const screenWidth=Dimensions.get('window').width;
const activeTab=this.getIndex(this.props.tabs.get('tab');
设coord=0;
如果(gestureState.dx>屏幕宽度*0.2){
坐标=(activeTab*屏幕宽度)-屏幕宽度;
}else if(gestureState.dx<-(屏幕宽度*0.2)){
坐标=(activeTab*屏幕宽度)+屏幕宽度;
}否则{
coord=activeTab*屏幕宽度;
}
this.updateTab(-coord,screenWidth);
回归协调;
}
更新选项卡(坐标,屏幕宽度){
//根据位置和屏幕宽度更新当前选项卡
this.state.tabs.forEach((tab)=>{
如果(坐标===-tab.index*屏幕宽度){
this.props.dispatch({type:'SET_TAB',TAB:TAB.name});
}
});
}
render(){
返回(
{this.state.tabs.map(tab=>tab.component)}
);
}
}

在使用代码块的视图控制器中(滚动视图、平移手势)

编写此函数:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
   return true
}

希望有帮助。:)

尝试使用onMoveS函数
onMoveShouldSetResponder: (evt, gestureState) => {
    return Math.abs(gestureState.dx) > Math.abs(gestureState.dy * 3);
},
checkSwipeDirection(gestureState) {
    if( 
        (Math.abs(gestureState.dx) > Math.abs(gestureState.dy * 3) ) &&
        (Math.abs(gestureState.vx) > Math.abs(gestureState.vy * 3) )
    ) {
        this._swipeDirection = "horizontal";
    } else {
        this._swipeDirection = "vertical";
    }
}
canMove() {
    if(this._swipeDirection === "horizontal") {
        return true;
    } else {
        return false;
    }
}
onMoveShouldSetPanResponder: this.canMove,
onPanResponderMove: (evt, gestureState) => {
    if(!this._swipeDirection) this.checkSwipeDirection(gestureState);

// Your other code here
},
onPanResponderRelease: (evt, gestureState) => {
    this._swipeDirection = null;
}
import RNLocky from "react-native-scroll-locky";

class WhateverClass extends Component {
  constructor(props) {
    super(props);
    this.directionLockPanHandler = new RNLocky(
      RNLocky.Direction.HORIZONTAL, // or RNLocky.Direction.VERTICAL
    );
  }


  render() {
      return (
          <ScrollView
              {...this.directionLockPanHandler.getPanHandlers()}
          >
            <ScrollView>
                ...
            </ScrollView>
          </ScrollView>
      );
  }
}