距上篇博文有间隔了好一阵。10月初,用RN写的app上架以后,马不停蹄地有整出来一份同业的版本,之后就全力进行二期的优化。其实就是填坑。每天忙忙碌碌,烦心事闹心事也不少。不过看到自己完成的app上store,同事夸app好用,心里还是美滋滋的。回首搞app开发这几个月,真是成长了不少。
言归正传,在这总结一下RN开发中的一些坑:
react-navigation
react-navigation作为官方推荐的导航跳转的工具,比起之前的navigator好用不少。当然也有不少问题。
- goBack()问题
react-navigation提供有goBack()这api, 但是使用返回栈中某个组件的方法this.props.navigation.goBack(‘component’)或this.props.navigation.dispatch(NavigationActions.back({key: “component”}))没有反应, 原理是因为这里的component不是用自定义的routeName而是用自动生成的随机值key. 又没有提供有api获取组件的key, 手动去获取又十分麻烦。这里我们可以修改他的源码:
把项目/node_modules/react-navigation/src/routers/StackRouter.js中
1 | const backRoute = state.routes.find((route: *) => route.key === action.key); |
改为:
1 | const backRoute = state.routes.find(route => route.routeName === action.key); |
这样的话,里的component要填想返回的组件的前一个组件的routeName, 比如你的栈里顺序是home1, home2, home3, home4, 在home4里要返回home2, 使用this.props.navigation.goBack(‘home3’);; 并且又会带出一个问题: goBack()方法没反应了, 必须加个null进去, 写成goBack(null)
- 快速点击多次跳转问题
当我们快速点击x按钮,请求跳转时。如果快速地点击两下,三下。会导致快速跳转。这里的解决方案是加入一个setTimeout函数。
修改react-navigation目录下,scr文件夹中的addNavigationHelpers.js
1 | export default function<S: *>(navigation: NavigationProp<S, NavigationAction>) { |
底部多个TextInput,输入法遮盖问题
安卓上貌似不会出现这个问题,主要是ios端。一开始使用的是原生的IQKeyBoardManager。但是多个TextInput情况下。支持的不是太好。这里使用了一块开源的组件:react-native-keyboard-aware-scroll-view 完美解决这个问题。
react-native-lightbox
这个组件实现了点击图片,灯箱效果。不过它的问题蛮多的。
遇到的第一个问题就是Pinch to zoom。这个组件本身不支持灯箱效果下,手势放大。这里使用了一个小技巧。通过本身的swipeToDismiss={false}以及ScrollView的minimumZoomScale和maximumZoomScale属性解决这个问题。
eg:
1 | <LightBox |
这个组件还有一个坑是,点击图片出现灯箱效果之后。IOS端的顶部StatusBar信息莫名其妙的消失了。排查了一大圈,发现是这个组件自己写没了。
这里需要修改一下源码
/node_modules/react-native-lightbox/LightboxOverlay.js:
135 line:
1 | StatusBar.setHidden(true, 'fade'); -> StatusBar.setHidden(false, 'fade'); |
scrollview的触摸滚动事件
在这里详细的列举一下:
1 | 1、onScrollBeginDrag:一个子view滑动开始拖动开始时触发,注意和onMomentumScrollBegin的区别 |
下面是在网上找到的两张图,分别是ios端的测试和Android端的:
WebView自适应高度
在做APP的时候遇到了一个需求就是希望页面中的文字可以复制。如果是Text组件下的。这个好说一个selectable={true}属性搞定。
但是selectable={true}这个属性。在ios端只支持整段话的复制。不支持,选哪儿复制那这种操作。之前查了一下好像是和底层OC代码有关。Android这块没有问题。
为了实现需求,采用了Webview的方式。(从接口的到的字段也是超文本类型的)。但是这里出现了一个问题就是WebView无法根据提供内容的多少自适应高度。
ReactNative中的WebView需要设定高度才能展示出来,因此需要用js来计算文档高度做到高度自适应。一个思路就是让WebView和React的JS进行通信。页面加载后,webview内的JS代码获取自己的高度,添加一个hash给自己的URL,React当感知到webview加载状态变化后,读取这个hash值,传递给this.state.WebViewHeight,从而改变WebView的高度。
第二种思路就是万能的github。试了好几个组件之后,一个国人开发的react-native-autoheight-webview最好用。
不过有一个诡异的现象是value值很少的情况下无法进行长按选中字段复制。字数多的时候 (4,5行以上)功能正常。这个问题的解决:
1 | // default width is the width of screen |
react-native-scrollable-tab-view
这个组件是tab切换用的。其实react-navigation也有这个功能。
它有一个问题是。在多个页面切换下无法正确的显示页面的高。默认选用的是最长的那个。(Tab view always has the height equal to height of the highest tab)
在issue上看到不少人碰到这个问题。一个不是很完美的解决方案就是:
Use ScrollView as tabs.
eg:
1 | <ScrollableTabView style={{ height: Dimensions.get('window').height }}> |
MAC对APK包进行重新签名
jarsigner -verbose -keystore [您的私钥存放路径] -signedjar [签名后文件存放路径] [未签名的文件路径] [您的证书名称]
1 | jarsigner的参数说明 |
以上
先总结这些,想到了再补充。RN还有太多太多知识需要掌握。原生,redux,优化。加油~