rn-relates icon indicating copy to clipboard operation
rn-relates copied to clipboard

口袋蜜蜂遇到的一些问题记录

Open ljunb opened this issue 8 years ago • 0 comments

1、InteractionManager 的 callback 失效

InteractionManager 接口的 runAfterInteractions 中的 callback 有时不触发,官方issue处理

2、TextInput 的 secureTextEntry 问题

TextInput 在 iOS 8 下,动态修改 secureTextEntry 属性时,光标位置发生变化,官方 issue 中网友提到的处理,自己项目中的处理:

// 明文显示密码
showPassword = () => {
  const { showPassword, passwordText } = this.state;
  this.setState({
    showPassword: !showPassword,
    passwordText: `${passwordText} `,
  }, () => {
    this.setState({ passwordText : this.state.passwordText.substring(0, this.state.passwordText.length - 1)});
  });
};

3、WebView 显示中文乱码

Android端,WebView 加载 HTML 内容显示中文乱码,项目版本是 0.50.0 ,处理方式:

<WebView
  source={{html: this.state.htmlContent, baseUrl: ''}}
  ...
/>

4、ScrollView 在 iPhone Plus 机型的事件拦截

上周 App 临近上线,QA 同事发现了一个奇葩问题:在 iPhone 6 Plus 跟 iPhone 7 Plus 两款机型中,在我的界面中点击不同条目来回跳转后,偶现重新点击条目无效了。调试时发现点击无效的时候,根本没有跑 TouchableOpacityonPress 方法。由于所有条目都包裹在 ScrollView 中,所以怀疑点击事件是被 ScrollView 给拦截了。在 issue 列表可以找到相关的,而且问题也是出在 Plus 系列机型。

一开始,是参考外国开发者提到的用 onPressIn 配合 delayPressIn 处理,但是运行后发现,滑动屏幕的时候,App 直接就拦截了手指的触摸事件,一下子跑到了 onPressIn 里面去了,导致 ScrollView 无法滑动。至于另外一位开发者提到的用的 TouchableWithoutFeedback ,也是依然有问题的。后来想着手势实现可视区域的滑动,实践下来发现效果并不理想,问题很多。 吃饭的时候,老大提了一句:有没用 ListView 试过?果然,回来一试确实可以!这脑子不好用了,这都没想到😶!

想来想去依然不明白,因为其他界面也有类似的布局实现,并没有发现这种问题,而且就只有 Plus 机型会……黑人疑问脸(⊙_⊙)?

5、自定义表情的图文混排

App 中即将上线 说说 业务模块,涉及到动态发布、评论和回复等一系列操作,其中涉及到了公司的自定义 emoji 表情,发布模块没有涉及 React Native ,不过评论、回复等通知列表,是基于 React Native 实现,需要进行自定义表情和普通文本的混排。

因为原生工程的资源文件中已经添加了表情图片,所以没有必要再在 React Native 新建目录来存放。这里可以通过以下方式来引用本地资源图片:

// import
const nativeImageSource = require('nativeImageSource');

// render image
const source = nativeImageSource(EmotionMap[item.source]);
return <Image key={`Emotion_${index}`} style={{height: 20, width: 20}} source={source} />

EmotionMap 是以自定义表情的名称为 key 、平台区分的本地资源名称为 value 的一个对象,格式如下所示:

{
  '[em2001]': { ios: 'em2001', android: 'drawable/em2001' },
  ...
}

Android 端的表情图片如果存放在 drawable-xx 目录下,直接 drawable/xxx 即可,mipmap 类似。混排方面,大抵是将文本内容进行正则匹配,切分成数组,按需添加一个 type 来区分普通文本和表情,再通过 map 或是 for 形式循环渲染所有内容即可。

6、手势处理

项目中的说说通知列表基于 react-native-scrollable-tab-view 实现,顶部分【赞我的】、【评论我的】两个 Tab 。当前界面去掉了手势返回,不过在往非切换 Tab 的方向滑动时,iOS 端会触发列表条目的点击事件,Android 端则不会触发,QA 的期望是不做响应。这个可以为每个条目加个手势处理,拦截掉特定方向的滑动手势:

componentWillMount() {
  this.panResponder = PanResponder.create({
    onMoveShouldSetPanResponder: (e, gestureState) => {
      const { tabType } = this.props;
      return tabType === 1 ? gestureState.dx > 0 : gestureState.dx < 0;
    }
  });
}

renderMsgRow = message => {
  const panHandlers = Platform.OS === 'ios' ? {...this.panResponder.panHandlers} : {};
  return (
    <View {...panHandlers}>
      <MessageCell message={message} onPress={this.handlePressMessageCell} />
    </View>
  );
};

利用 gestureState.dx 的值来判断手势滑动方向,虽然拦截了,但是不做处理,就避开了触发条目点击的事件。因为只有两个 Tab ,所以根据 Tab 类型来区分处理。

7、Text 关于 allowFontScalingfontFamily 的处理

项目在 iOS 端是去掉了字体随系统缩放功能,为了能全局应用,使用了以下处理方式:

import _ from 'lodash';

Text.prototype.render = _.wrap(Text.prototype.render, function (func, ...args) {
  const originText = func.apply(this, args);
  return React.cloneElement(originText, {
    // Android平台可以跟随APP设置字体大小
    allowFontScaling: Platform.OS === 'android',
  });
});

在入口文件引入即可。在 QA 的测试过程中,发现 OPPO R9 和一加手机都存在粗体文字截断的问题,即是显示不全,其他机型都正常。在官方找到相关的问题,对应解决方法:

import _ from 'lodash';

const styles = StyleSheet.create({
  defaultFontFamily: {
    ...Platform.select({
      android: { fontFamily: 'lucida grande' },
    }),
  },
});

Text.prototype.render = _.wrap(Text.prototype.render, function (func, ...args) {
  const originText = func.apply(this, args);
  return React.cloneElement(originText, {
    style: [styles.defaultFontFamily, originText.props.style],
    allowFontScaling: Platform.OS === 'android',
  });
});

8、Flex 布局样式在 iOS 8 适配

这其实不是跟进口袋蜜蜂时遇到的问题,电脑资讯网最近需要上一个补丁需求。相关的技术点,是原生 WebView 加载本地 HTML 文件,网页文件是基于 Vue 实现的。新需求在开发完后,发现在 iOS 8 下样式错乱了。初始定位觉得是 iOS 版本问题,不过自己不怎么熟悉前端开发,找了同事协助,他发了我一个链接 CanIUse,里面可以查 Flex 布局在各种浏览器或是移动端上所支持的写法,果不其然,一查发现确实是写法有错。最后的解决方法是在 Flex 布局相关的属性上,添加-webkit-前缀即可:

// style.css

.art-coupon-title {display:-webkit-flex;-webkit-align-items:center;margin-left: 18px}

ljunb avatar Nov 15 '17 09:11 ljunb