React-Native 0.63踩坑之旅--react-native使用字体图标库

2,189 阅读7分钟

目录

前言

在web前端工程开发时,如果需要使用纯色的图标时,那么绝大多数都会使用字体图标库。它的优点很显著,例如:

  • 它是矢量图,无论放大还是缩小图标都不会失真
  • 针对移动端开发时也不用考虑1x、2x、3x图的问题
  • 字体文件大小要比多个图片小,节省空间

那么在RN的开发中能使用字体图标库吗?答案是可以的。

如何使用字体图标库

在web前端中通过css就可以支持字体图标库,但是要想在RN中使用字体图标库,需要借助第三方组件来完成,即: react-native-vector-icons

官方git地址

react-native-vector-icons官网

目前最新版本的 react-native-vector-icons 包含如下字体:

  • AntDesign by AntFinance (297 icons)
  • Entypo by Daniel Bruce (411 icons)
  • EvilIcons by Alexander Madyankin & Roman Shamin (v1.10.1, 70 icons)
  • Feather by Cole Bemis & Contributors (v4.28.0, 285 icons)
  • FontAwesome by Dave Gandy (v4.7.0, 675 icons)
  • FontAwesome 5 by Fonticons, Inc. (v5.13.0, 1588 (free) 7842 (pro) icons)
  • Fontisto by Kenan Gündoğan (v3.0.4, 615 icons)
  • Foundation by ZURB, Inc. (v3.0, 283 icons)
  • Ionicons by Iconic Framework (v5.0.1, 1227 icons)
  • MaterialIcons by Google, Inc. (v4.0.0, 1547 icons)
  • MaterialCommunityIcons by MaterialDesignIcons.com (v5.3.45, 5346 icons)
  • Octicons by Github, Inc. (v8.4.1, 184 icons)
  • Zocial by Sam Collins (v1.0, 100 icons)
  • SimpleLineIcons by Sabbir & Contributors (v2.4.1, 189 icons)

由此可见这个组件包含了非常多的图标。在项目或者产品可以选择其中1个字体库也可以选择多个字体库一起使用。

安装 react-native-vector-icons

安装命令如下:

yarn add react-native-vector-icons
# 或者使用npm进行安装
npm i react-native-vector-icons -S

平台配置

这个组件需要根据不同的平台进行不同的配置,下面分别介绍

ios 端

自动配置

# RN版本大于60
cd ios
pod install

# RN版本小于60可以通過 如下命令進行自動配置
react-native link react-native-vector-icons

之后可以尝试打开xcode运行工程,如果能顺利运行,那说明你很幸运,如果不能顺利运行就需要手动的方式进行配置了。推荐手动进行配置,因为自动不成功后需要删除很多内容。例如

  • 如果使用link方式,则需要删除Resources文件夹、info.plist里面的Fonts provided by application属性、Build Phases中的Copy Bundle Resources字体连接

  • 如果是pod install方式自动配置的,主要就是删除Build Phases中的[CP]Copy Bundle Resources字体连接

手动配置xcode

如果自动配置不成功就需要手动配置。

**注意:**手动配置前千万不要使用pod install,否则即使手动配置完,也不会成功。原因在于手动配置会和自动配置产生冲突。

手动配置的步骤如下:

  • 先执行安装react-native-vector-icons
npm i react-native-vector-icons -S 
# 或者 yarn react-native-vector-icons

  • 双击运行ios目录下的 *.xcworkspace 文件打开工程。在工程的根目录下创建资源文件夹(本例使用的名称Fonts,这个名称随便写,只要不是中文的)
  • 之后找到node_modules文件夹里面的react-native-vector-icons/Fonts文件夹,将里面的所有字体文件选中。并且拖拽到刚刚创建好的Fonts文件夹中。此时Xcode会弹出一个提示框。如下: 此时选中Create Groups和Add to targets中的第一个checkbox,之后点击确定。
  • 然后点击工程图标,查看Build Phases中的Copy Bundle Resources中是否也添加了这些字体库
  • 最后一步到项目目录里面的Info.plist添加一个Fonts provided by application选项并且将字体图标的名称都添加进去。如下所示:

按照以上步骤就完成了ios的手动配置工作。现在可以用Xcode或者yarn ios来运行工程了。

android端

可以参考这篇文章的内容

字体库的如何使用

如果没有特殊需求,react-native-vector-icons里面已经有足够多的图标了,所以可以去react-native-vector-icons官网去查找图标的名字,然后在工程中使用

import AntDesignIcon from 'react-native-vector-icons/AntDesign';
<AntDesignIcon
    name={'rightcircle'}
    size={30}
/>

//rightcircle 就是对应自图库的名称。

如何扩展字体库图标

虽然说react-native-vector-icons图标已经足够多了,但是难免由于项目或者产品的需求会有一些如logo一类的图标。那么如何使用扩展呢。作为前端工程师,我知道有一个阿里巴巴字体库网站,在这个网站上可以上传svg并且生成相应的字体文件。在这个网站将字体下载下来后。压缩包里面会有*.ttf和*.json,这两个文件才是我们需要的文件。

根据react-native-vector-icons官方文档介绍。有三种方法可以添加自定义图标。包括:

  • createIconSet(glyphMap, fontFamily[, fontFile])
  • createIconSetFromFontello(config[, fontFamily[, fontFile]])
  • createIconSetFromIcoMoon(config[, fontFamily[, fontFile]])

我使用的阿里巴巴的字体库所以得使用第一种方法来实现。 这种方法是基于node_modules/react-native-vector-icons包来完成的,详细的步骤如下:

  • 先去阿里巴巴字体库网站去寻找自己心仪的图标或者上传svg来制作图标。最后将选择好的字体库下载下来。
  • 下载下来的zip文件,内容如下,其中iconfont.ttf和iconfont.json是后续要使用的两个文件

  • 将iconfont.ttf文件拷贝到node_modules/react-native-vector-icons/Fonts文件夹下。
  • 在node_modules/react-native-vector-icons/glyphmaps 文件夹下创建一个和字体库同名的json文件,例如Iconfont.json,这个文件key就是未来要使用的name,key是一个数字。这个数字是上述下载下来zip包的iconfont.json中的unicode_decimal所对应的值。

最终生成的json文件为:

{
  "iconfont_weixin": 58934,
  "iconfont_qq": 58880
}

这个过程可以使用nodejs写一个小工具根据zip里面的iconfont.json文件的内容来生成这个新文件。

  • 在node_modules/react-native-vector-icons文件夹下再创建一个和字体库同名的js文件,内容大致如下:
import createIconSet from './lib/create-icon-set';
import glyphMap from './glyphmaps/Iconfont.json';

//第一个参数为json文件 第二个参数为font_family 第三个为字体文件
const Iconfont = createIconSet(glyphMap, 'iconfont', 'Iconfont.ttf');

//输出字体图标控件
export default Iconfont;

export const Button = Iconfont.Button;
export const TabBarItem = Iconfont.TabBarItem;
export const TabBarItemIOS = Iconfont.TabBarItemIOS;
export const ToolbarAndroid = Iconfont.ToolbarAndroid;
export const getImageSource = Iconfont.getImageSource;
  • 上述步骤完成后,用手动的方式将iconfont.ttf这个字体添加到xcode工程中。之后就可以像其他字体一样来使用这个字体库了。
import Icon from 'react-native-vector-icons/Iconfont';
<IconfontIcon
    name={'iconfont_weixin'}
    size={30}
/>

总结

当工程中即使用了antd-mobile-rn又使用了react-native-vector-icons那么工程在构建会出现冲突。原因在于antd-mobile-rn在安装时需要link字体库。使用的是npx react-native link 指令来自动构建。再加上RN > 60 安装依赖需要使用pod install。尤其当工程安装了react-native-vector-icons后,在执行pod install时候就将字体关联到工程上,主要体现在Build Phases中的[CP]Copy Bundle Resources上。如果安装完antd-mobile-rn后执行npx react-native link 由于在Build Phases中的Copy Bundle Resources又关联一遍字体。因为引用两次的原因就导致ios build工程失败。

为了解决这样的冲突的问题,可以执行pod install来关联[CP]Copy Bundle Resources,之后再执行npx react-native link,此时会在resource下面把所有的字体库又关联到Copy Bundle Resources,这时运行肯定会冲突,所以此时删除resource除了antd-mobile-rn以外(antfill.ttf和antoutline.ttf以外)的字体。这是观察Build Phases中的Copy Bundle Resources只保留了antfill.ttf和antoutline.ttf引用。此时就不会冲突了。直接运行工程即可。