React native:如何在wix中单击按钮选项卡时打开模式或动作表react本地导航

时间:2019-06-09 09:33:29

标签: javascript reactjs react-native wix-react-native-navigation

如何使用 wix react native navigation v2 单击基于选项卡的应用程序底部的选项卡来打开模式/动作表?

当前,我正在使用以下软件包和版本:

  • 本机:“ 0.59.8”
  • 反应:“ 16.8.3”
  • react-native-navigation:“ ^ 2.13.2”
  • react-native-image-crop-picker:“ ^ 0.24.1”

这是我的路线/导航文件

 Promise.all([
        Foundation.getImageSource("home", 40),
        FontAwesome5.getImageSource("user",30),
        Feather.getImageSource("camera",25),
    ]).then(sources => {
        Navigation.setRoot({
            root: {
                sideMenu: {
                    center: {
                        bottomTabs: {
                            options: {
                                bottomTabs: {
                                    backgroundColor: 'white',
                                    titleDisplayMode: 'alwaysHide'
                                },
                            },
                            children: [
                                {
                                    stack: {
                                        children: [{
                                            component: {
                                                name: 'HomeScreen',
                                                passProps: {
                                                    text: 'This is tab 1'
                                                }
                                            }
                                        }],
                                        options: {
                                            bottomTab: {
                                                testID: 'HOME_TAB',
                                                icon: sources[0],
                                            },

                                            topBar: {
                                                title: {
                                                    text: 'MyReactApp',
                                                }
                                            }
                                        }
                                    }
                                },
                                {
                                    component: {
                                        name: 'Camera',
                                        passProps: {
                                            text: 'This is tab 2'
                                        },
                                        options: {
                                            bottomTab: {
                                                testID: 'CAMERA_TAB',
                                                icon: sources[2]
                                            }
                                        }
                                    }
                                },
                                {
                                    stack: {
                                        children: [{
                                            component: {
                                                name: 'ProfileScreen',
                                                passProps: {
                                                    text: 'Profile Screen'
                                                }
                                            }
                                        }],
                                        options: {
                                            bottomTab: {
                                                testID: 'PROFILE_TAB',
                                                icon: sources[1],
                                            },
                                            topBar: {
                                                title: {
                                                    text: 'John Doe',
                                                }
                                            }
                                        }
                                    }
                                }
                                ]
                        },
                    },
                },
            }
        });
    });

我想要的是,当用户单击camera选项卡时,它应该打开一个模式/动作表,该模式/动作表将显示他应该从相机胶卷中选择图像还是应该打开相机的选项。为此,我想使用react-native-image-crop-picker。但是,我该如何实现呢?或者如何自定义按钮的标签按下动作呢?

我看过Google,但除了这些链接外,没有找到其他任何帮助

https://github.com/wix/react-native-navigation/issues/3238

https://github.com/wix/react-native-navigation/issues/2766

https://github.com/wix/react-native-navigation/issues/3204

2 个答案:

答案 0 :(得分:0)

执行此操作的一种方法是使用componentDidAppear事件。每次将组件连接到视图层次结构时都会调用此事件(因此出现)。根据文档componentDidMount()(https://wix.github.io/react-native-navigation/#/docs/events?id=componentdidappear的介绍,它或多或少地以与React Native生命周期API(例如componentDidMount)相同的方式使用,不同之处在于您需要对其进行“监听”。 )

然后,您可以在Camera组件的componentDidAppear()中使用一些逻辑来显示模式或叠加,并传递作为道具的功能来更改Camera组件的状态并根据选择进行渲染。以下示例使用RNN文档中的componentDidAppear()示例。免责声明,我没有测试它,但是应该可以。

class Camera extends Component {
  constructor(props){
      super(props);

      // Don't forget to bind the setMode function
      this.setMode = this.setMode.bind(this);

      // Edit: catch the tabchange
      this.eventSubscription = Navigation.events().registerBottomTabSelectedListener(this.tabChanged);

      this.state = {
         mode: 'default'
      }
  }

  componentDidMount() {
    this.navigationEventListener = Navigation.events().bindComponent(this);
  }

  componentWillUnmount() {
    // Not mandatory
    if (this.navigationEventListener) {
      this.navigationEventListener.remove();
    }
  }

  componentDidAppear() {
      Navigation.showModal({
          component: {
              // Example name, don't forget to register the modal screen
              name: 'modals.ImageModeChoiceModal',
              passProps: {
                  setMode: this.setMode,
                  // Edit pass the index of the unselected tab to the modal
                  fromTab: this.fromTab
              }
           }
      });
  }

  setMode(mode){
      this.setState({
          mode: mode
      });
  }

  // Edit: callback that will be fired on the bottomTabSelectedListener
  // Tracks the selected and unselected tab index
  tabChanged = (selectedTabIndex, unselectedTabIndex}) => {
      this.fromTab = unselectedTabIndex;
  }

  render(){
      if(this.state.mode === "camera"){
          return( 
                // Camera component
          );
      } else if(this.state.mode === "roll"){
          return( 
                // Camera roll component
          );
      } else {
          return(
                // Default component
                // You could also choose to implement the user choice logic 
                // here
          )
      }
  }
}

编辑:作为后续问题,出现了处理向后导航行为的问题。在backpress或modalclose上,模态关闭并最终转到Camera组件(在这种情况下为屏幕/选项卡)。这是因为选择了选项卡,并且在“相机”组件的“外观”上打开了模态。导航道具不包含有关所按下的选项卡的信息。因此,您需要在其他地方获取有关它的信息。您可以在“相机”组件中添加一个导航事件侦听器,以拦截选定和未选定的标签索引(例如:https://github.com/wix/react-native-navigation/issues/4109,文档:https://wix.github.io/react-native-navigation/#/docs/events?id=registerbottomtabselectedlistener

在模态组件中,您应该添加一些逻辑以处理backpress / back行为(来源:https://facebook.github.io/react-native/docs/backhandler.html):

  ...

  componentDidMount() {
    this.backHandler = BackHandler.addEventListener('hardwareBackPress', this.handleBackPress);
  }

  componentWillUnmount() {
    this.backHandler.remove()
  }

  handleBackPress = () => {
    this.closeModal();
    return true;
  }

  // Can also be used to implement close button behaviour (eg. on iOS)
  closeModal(){

      // Dismiss the modal itself
      Navigation.dismissModal(this.props.componentId);

      // This changes the active tab programmatically
      // Don't forget to add a bottomTabsId to your bottomTabs configuration
      Navigation.mergeOptions('bottomTabsId', {
          bottomTabs: {

              // Using the index of the unselected tab passed from the Camera component
              currentTabIndex: this.props.fromTab
          }
      });
  }

  ...

ps:根据RNN文档,dismissModal将'mergeOptions'作为第二个参数,但是我尚未使用或测试该参数,但这可能意味着Navigation.mergeOptions可以集成在Navigation.dismissModal调用中。 (文档:https://wix.github.io/react-native-navigation/#/docs/screen-api?id=dismissmodalcomponentid-mergeoptions

答案 1 :(得分:0)

据说v2的文档比v1发行版差。我正在使用这个包。通常,我会通过查看源代码来解决无法解决的问题。我必须说这很有用。这有点挑战,但确实有帮助。

值得再次记住; 在React结构中,所有内容都是组件

有很多方法; (现在想到的是什么)

  1. 您创建自己的组件并将其连接到bottomTab。触发此组件后,您可以显示wix的模式或react-native的模式。
  2. 尽管以上仍然有效;您可以使用 passProps 完成。但是请记住,执行此操作时,链接到bottomTab的页面也会出现。

作为解决方案;

您不必使用Wix的模态。坦白说,我不喜欢它,因为我期待的是Bootstrap的模式风格,我使用的是react-native自己的模式。这是您的决定。

您可以使用我编写的任何bottomTab解决方案,也可以自己创建解决方案。 Wix为此提供了很大的可能性。

您还可以在模式框中添加可触摸的按钮,并指定要打开相机还是打开画廊。

我已经在模块的仓库中看到了示例代码。

如果我无法解释它,我可以创建一个示例存储库:/