反应本机触摸捕获行为已更改

时间:2020-06-23 15:41:31

标签: react-native expo

使用旧版本的Expo,我创建了一个应用程序,该应用程序必须在按下自定义按钮时播放音频流,并且由于Expo不支持后台播放,因此我决定使用保持唤醒状态,并将该应用程序演化为通过将屏幕变黑来模拟睡眠。我知道这不是最佳解决方案,但是鉴于世博会的限制,这可能是我可以做出的最佳折衷方案。要开始倒计时,应该在屏幕上的任何位置检测到触摸,并且每次检测到触摸时,都必须重置倒计时。在浏览Expo版本时,有一次,我开始使用View的onTouchStartCapture,那时即使按下子TouchableOpacity按钮并且事件由孩子处理,它也可以工作并捕获触摸。

但是,现在使用37(我正在使用〜37.0.3)和React Native 37.0.1,一切都不同了,即使我在线上进行了研究,我还是有点迷失。

即使在孩子处理的情况下,是否也可以正确捕获父母中的触摸事件?我的意思是,即使事件是在父母中捕获的,孩子的行为也不应受到影响。我尝试在冒泡阶段进行捕获,但是无法按预期进行。

该代码过于复杂,无法发布有意义的示例,除了小片段外(可能用于SleepOverlay)。

const SLEEP_TIMEOUT_1 = 24000
  , SLEEP_TIMEOUT_2 = 6000

class SleepOverlay extends React.Component {
  _state = 0
  _timeout1 = null
  _timeout2 = null
  state = {
    opacity: .7
    , visible: false
  }
  clearTimeouts = a => {
    clearTimeout(this._timeout2)
    clearTimeout(this._timeout1)
  }
  sleep = e => {
    this.state = 3
    this.setState({ opacity: 1, visible: false })
    this.setState({ visible: true })
  }
  shade = e => {
    this.state = 2
    this.setState({ visible: true })
    this._timeout2 = setTimeout(this.sleep, SLEEP_TIMEOUT_2)
  }
  wait = a => {
    this.clearTimeouts()
    this.state = 1
    this._timeout1 = setTimeout(this.shade, SLEEP_TIMEOUT_1)
  }
  constructor(props) {
    super(props)
    const onInit = this.props.onInit
    if(onInit)
      onInit(this.wait)
  }
  componentWillUnmount() {
    this.clearTimeouts()
    this.state = 0
  }
  componentDidUpdate() {
    if(this.props.visible) {
      if(this.state === 0)
        this.wait()
    } else {
      this.clearTimeouts()
      this.state = 0
    }
  }
  pressed = e => {
    this.state = 0
    this.setState({ opacity: .7, visible: false })
  }
  style() {
    return {
      position: 'absolute'
      , top: 0
      , right: 0
      , bottom: 0
      , left: 0
      , backgroundColor: '#000'
      , opacity: this.state.opacity
    }
  }
  render() {
    return (
      this.state.visible && this.props.visible && (
        <TouchableOpacity
          style={ this.style() }
          onPress={ this.pressed }
        />
      ) || <></>
    )
  }
}

应用程序:

  sleepReset() {}
  captureTouched = a => this.sleepReset()
  initSleepOverlay = f => this.sleepReset = f

渲染:

return (
  <View
    onTouchStartCapture={ this.captureTouched }
  >
    <ScrollView
    >
    </ScrollView>
    {isIOS && isPortrait &&
      <TouchableOpacity style={ styles.iosBar } />
    }
    <SleepOverlay visible={ state.tag } onInit={ this.initSleepOverlay } />
  </View>
)

0 个答案:

没有答案