美文网首页iOS进阶iOS小记iOS开发系列
为视图添加丝滑的水波纹

为视图添加丝滑的水波纹

作者: WelkinXie | 来源:发表于2016-08-15 23:29 被阅读2959次

简书文章不再更新、管理。
评论留言欢迎移步 https://welkinx.com/2016/08/14/11/ :)

由于前段时间发现自己在Github上的这份代码被简书上某用户直接拷贝来发表了,而又并没有注明代码出处,于是决定还是自己着手写一篇好了。

先看一下最终效果图:

首先我们可以把如此丝滑的水波纹拆分一下下:

  • 一条规律的曲线。
  • 曲线匀速向右移动。
  • 曲线下方的位置用颜色填充。

于是先来一条曲线吧。

对于需要产生波动如此规律的曲线,我们首先想到的应该就是三角函数了。

例如我们熟悉的正弦曲线:

及其公式:

f(x) = Asin(ωx+φ)+k

而SDK也为我们提供了这个正弦函数:

extern double sin(double);

于是乎通过一个循环就能轻易地获取到这条曲线了:

CGFloat y = 0.f;
for (CGFloat x = 0.f; x <= CGRectGetWidth(self.frame) ; x++) {
    y = height * sin(self.angularSpeed * x + self.offsetX);
    CGPathAddLineToPoint(path, NULL, x, y);
}

让它动起来

我们需要在屏幕每次刷新的时候进行一次曲线的绘制,让它不断地刷新。

self.waveDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(currentWave)];

而根据上面的正弦函数公式,曲线要向右移,其φ值就需要变小。于是在 currentWave 方法每次调用的时候,offsetX均减去同一个固定值,以实现匀速的运动。

self.offsetX -= self.waveSpeed;

涂个颜色

连个线,形成封闭空间:

CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, 0, height / 2);

CGFloat y = 0.f;
for (CGFloat x = 0.f; x <= CGRectGetWidth(self.frame) ; x++) {
    y = height * sin(self.angularSpeed * x + self.offsetX);
    CGPathAddLineToPoint(path, NULL, x, y);
}
CGPathAddLineToPoint(path, NULL, width, height);
CGPathAddLineToPoint(path, NULL, 0, height);
CGPathCloseSubpath(path);

再填个色:

self.waveShapeLayer.fillColor = self.waveColor.CGColor;

好了。

至于最后的渐变消失略简单就不说了。有兴趣的直接到文末下载完整代码吧~

多扯两句

这水波纹并不限定在拖动过后才能波动,而是随时想动就动、想停就停。

于是最近我想到了一些新玩法,例如用作刷新等待视图。

更多的玩法就自行发掘吧~

最后

完整代码呈上:

Github: WXWaveView

其使用方法在该页面中会有介绍。

喜欢的欢迎给个star~玩得开心哈。

相关文章

网友评论

  • Victor123:楼主这是什么语言写的??
    WelkinXie:@Victor123 swift :flushed:
  • Thebloodelves:可以的,这个我有次面试遇到过
    WelkinXie:@Thebloodelves :flushed: 原来如此~
    Thebloodelves:@WelkinXie 就是这个效果怎么做出来
    WelkinXie:@Thebloodelves :smile:真的吗 可以分享一下具体的面试题目是怎样吗
  • _zhouxl:我是第100个赞,哈哈哈
    WelkinXie:@顶起_那片天 感谢你让我到达这个里程碑:smile:
  • Jaesun:你好,今天在code4app 上发表了一个demo ,引用了你的文章,本来是放了个链接,但后来被管理员过来把你的代码复制过去放那里了,挺不好意思的,但是他们网站我没有删帖权限。希望你能谅解。不过我发个一个置顶的回复已经说明了,正文的来源。
    WelkinXie:@Jaesun 嗯嗯 好的~ :smile:
    Jaesun:@Jaesun 当然我不是作者文中提的那个。
  • 漂泊海上的大土豆:代码简单易懂 赞一个 已经给星星
    WelkinXie:@漂泊海上的大土豆 谢谢:grin:
  • ca04a13f364c:赞赞赞
    WelkinXie:@nolews :blush:
  • Oniityann:666, 羡慕数学好, 还记得数学公式的人
    WelkinXie:@Oniityann :smile::smile:
  • 无神:效果不错,收藏了,为作者赞一个! :+1:
    无神:@WelkinXie :smiley::blush:
    WelkinXie:@无神 谢谢:blush:
  • Jaesun:Mark
  • 红鲤鱼蓝鲤鱼与驴: y = height * sin(0.01 * self.angularSpeed * x + self.offsetX * 0.045);
    这里为什么(ωx+φ)要x0.01,不是很懂,麻烦楼主解答一下。。。
    红鲤鱼蓝鲤鱼与驴:@WelkinXie 这样啊。。。谢谢楼主回答
    WelkinXie:@红鲤鱼蓝鲤鱼与驴 呃,再简单点说就是ω,φ的数量级太大。为了方便使用,不用在使用的时候传入0.06之类蛋疼的angularSpeed而做的步骤。
    WelkinXie:@红鲤鱼蓝鲤鱼与驴 这只是为了方便使用者设置参数的,因为如果按照平常的习惯直接设置angularSpeed为1,2之类的数值的话,最后得出的ω就会很大,图形就会不是想要的那种样子。所以我才自己默认把用户设置的角速度缩小。后面0.045同理的。
  • 豫风:赞一个
    WelkinXie:@豫风 谢谢:grin:
  • 1ca631060677:6666666666 :+1: 下次直接拿来用
    WelkinXie:@iOS码农 可以可以~
  • Zhang_yD:效果好漂亮..
    WelkinXie:@Zhang_yD :blush:
  • 判若两人丶:支持一下
    WelkinXie:@判若两人丶 谢~
  • ccc7cdab373b:可以很强势
  • ccc7cdab373b:6666
    WelkinXie:@jerryIOS :flushed:
  • 无夜之星辰:可以,很强势。最瞧不起那种拿别人的东西还说是自己的人,发现简书上有不少文章都是直接copy的
    WelkinXie:@无夜之星辰 :smile:
  • Rickie_Lambert:太帅了这个 , 让我可以模仿拉勾的app写个东西了
  • Rickie_Lambert:github 给你个星
    WelkinXie:@雨神Rain 感谢你的星 :blush:
  • 86f079ca8043:给勤奋喜欢分享的楼主一个赞
    WelkinXie:@Jeff_Dexter :joy:
  • LeeLom:给楼主一个赞
    WelkinXie:@LeeLom 谢谢 :flushed:

本文标题:为视图添加丝滑的水波纹

本文链接:https://www.haomeiwen.com/subject/agxpsttx.html