最近在做一款教育类的app,新的APP涉及了数理化公式展示,也是第一次接触。百度、谷歌下发现资料有限。可以搜到一个开源的demo:https://github.com/CodingSha/SPMathKit
我看了下这个demo的实现逻辑是通过web去渲染公式,生成图片然后跟富文本拼接来实现公式展示。开始我也是按照这个demo的逻辑,来实现我的需求。公式倒是能展示出来,满心以为万事大吉。但是随着项目的开发推进,发现事情没有想象的那么简单。从服务端请求数据使用才发现问题特别多,很多公式跟文本并不能对齐。(这里不得不再次吐槽下苹果糟糕的UI布局方式,是需要计算、计算、计算。糟心的事情说三遍)这还是小问题;最让人难以接受的是加载公式的时间;经过测试,如果同时加载5个公式基本在2秒以上!! 这对于我来说是难以接受的。如是就只能继续摸索怎么解决这个问题了。
继续在谷歌上不停的搜索资料,结果让我很绝望,安卓的开源资料很多、iOS的几乎没有、做开发最怕的不是你碰到的东西有多难,而是你根本就找不到资料;(swift也有latex的资料、我没试过效果怎么样、因为我项目没打算用swift混编)后面在某乎上发现一个专门弄latex的大神,我翻看了他之前写的文章,有一篇文章专门写了关于laxte转译iOS跟安卓的,不过他需要付费使用并未开源,根据他文章的思路、我尝试自己写一个、先进行公式绘画,绘画成功后通过NSMutableAttributedString进行富文本拼接。那么下面就来说下我的思路。
在这里我是用的的是iosMath这个转化公式的库。好像也只有这个能用来解决当前的问题。
使用MTMathUILabel这个类去加载你需要展示的公式。例如你需要去展示 mathLatex = @"F(X) = P\left\{ {X \le x} \right\} = \left\{ \begin{array}{l} 0,x < 0\\ 0.2,0 \le x < 1\\ a,1 \le x < 2\\ 1,x \ge 2 \end{array} \right."这么样一个公式,你只需要简单的去实现一个类似label复制的操作。
就可以很完美的展示出来你要的公式。
如果你觉得事情到这就结束了。那不好意思,我只能用叶问里洪师傅的一句话来回复:“没那么简单”。
iosMath是能解决公式的展示问题,但是也有缺陷的。1.它不能展示除公式外的其它元素。2.有许多公式他是不支持的,这也是我在实践中得出的血泪史。
那么关于不能展示其它的字符,这个很好解决。我们可以利用强大的富文本来拼接实现。我们可以把后台返回的题目进行切割,分离出公式模块和非公式模块。根据特定的字符切割。然后将MTMathUILabel展示的latex放到一个view上,当然view要适配公式的高度。话不多说,先上代码
这样解决了基础的公式展示需求,当然这样可以很好地解决ios的控件适配。那么到这里,基础的需求没有毛病。但是随着程序的继续,最恶心的来了。你会发现你有很多公式完全解析不了。这特么就尴尬了,没有办法,只能遇到问题解决问题。办法总比困难多。
这里需要一个转化公式的工具,这个网上很多。然后需要我们去latex官网对准标准格式。我遇到的是很多双重积分、矩阵公式不能解析。打开iosMath源码,进去看看源码
这个方法里面有很多公式的转码,你需要自行比对。例如需要展示 "积分$\\int_0^1 {dx} \\int_0^{1 - x} {f(x,y)} dy$交换积分次序后等于( ) <br \/>"这个题目,但是你在iosMath里却根本没有发现有这个二重积分的转化,那么就需要自己进去修改源码。
这里加上二重积分的函数。效果如下
这是个痛苦的过程,因为我不认识那些特殊的字符代表的是个啥公式到底。反正记住一句话《公式显示有问题请到latex官网对准标准格式》。现在我这边百分之90左右公式是没有问题了,也还有一些公式还是渲染有问题,各种比对和修改,目前还是有点问题。只能继续摸索。抛开其它不说,其实这个东西搞起来也很有意思。如果哪位大神有个好的想法,请告诉小弟。
两位老哥,交流的过程,解决了我好几个问题。thank you