Swift下‘有趣的’渐变和遮罩

很长时间没有写文章了,人变懒惰了。
很早之前看见一个公式:每天进步一点点,一年下来,你会发现进步很多。每天不进步,一年下来就会倒退很多。“逆水行舟,不进则退”,说的就是这个道理。

计算公式

好了,闲话不多说。 今天的主角是 CAGradientLayer。我将这篇文章归类为iOS Animation,因为在后续的教程中,我将会讲解如何利用CAGradientLayer创建动画`后续会有系列教程,敬请期待。

一、开始

文章中使用的开发环境是xcode9.1 , 用的是swift语言。关于CAGradientLayer是什么,这里就不做过多解释了,想要了解的朋友们,可以自己下去看苹果文档,或者百度一下。 最终效果键本文最后面附的图 完整项目下载地址.

  • 1.1 首先我们在viewDidAppear()方法中创建一个渐变。
let gradient = CAGradientLayer() // 创建一个渐变层
gradient.frame = view.bounds     // 设置frame(全屏显示)
gradient.startPoint = CGPoint(x: 0, y: 0) // 设置开始点
gradient.endPoint = CGPoint(x: 1, y: 1)   // 设置结束点

可能有朋友会有疑问,开始点和结束点为什么是 (0, 0)和(1, 1)呢? 别急,看看下图就知道了。


开始点和结束点

当我们运行代码后,发现什么都没有。 当然啦,你要设置渐变色,首先你得设置CAGradientLayer的颜色,最重要的一步,你还要把它添加到View的layer上面。下图是显示效果

  • 1.2 将gradient添加到控制器视图的layer上
// 设置渐变色(这里需要传递一个color数组)
gradient.colors = [UIColor(red: 0.0, green: 1.0, blue: 0.752, alpha: 1.0).cgColor, 
                   UIColor(red: 0.949, green: 0.03, blue: 0.913, alpha: 1.0).cgColor]
// 将gradient添加到控制器视图的layer上 
view.layer.addSublayer(gradient)

[图片上传失败...(image-c1eb26-1511180450498)]


效果图

看,是不是很漂亮?你也可以设置你自己喜欢的颜色。

二、渐变和UILabel结合

接下来,我们看看,当渐变和UILabel结合会是什么样子的。

按住键盘上的control+command 点击CAGradientLayer,会跳到它的定义。我们发现CAGradientLayer是继承CALayer的,CALayer有一个mask属性,mask属性???什么鬼?

CALayer的头文件关于mask的说明,mask实际上layer内容的一个遮罩,如果我们把mask是透明的,实际看到的layer是完全透明的,也就是说只有mask的内容不透明的部分和layer叠加的部分才会显示出来。

为了方便,我直接在storyBoard上拖了一个UILabel,并设置gradient.mask = label.layer;。 再次运行项目可以看到的单词“文本”不是以其原始的黑色显示,而是在显示上文中我们设置的渐变颜色。为了使效果更酷,我们添加了一些动画,让其看起来更加有趣。

// UILabel动画, 需要传入一个字符串
func animateText(text: String) {
    // text的长度大于0才会运行这个动画
    if text.characters.count > 0 { 
        // startIndex : 第一个字符的位置 
        // text.index(after: text.startIndex) 给定位置之后的字符位置 
        // 下面两句的组合起来完成了本动画:label的文本从传入的字符串的第一个字符开始,每隔0.05秒添加一个字符到label上面,直至结束。
        label.text = "\(label.text!)\(text.substring(to: text.index(after: text.startIndex)))"
        delay(0.05, task: { // delay 是封装的一个延时方法,后面工程中会给出这部分封装的代码。
            self.animateText(text: text.substring(from: text.index(after: text.startIndex)))
        })
        
    } else {
        // 结束Label动画,如果要做别的操作,在这里添加代码
    }
}

关于上面动画的说明:每0.05秒添加一个字符到label上,直到有字符添加。 它会自己递归地调用,所以你只需要用全文调用一次,然后让它自己工作。别忘记了在 viewDidAppear方法中调用 animateText(text: "需要显示的内容") 这个方法。下面是运行效果:


效果图

是不是很酷?😎😎😎。 我们还可以为gradient添加更多的mask,比如说添加一个按钮动画:

func addButtonRing() {
    let side: CGFloat = 60.0
    let button = CAShapeLayer() // CAShapeLayer 绘制圆环
    button.position = CGPoint(x: label.bounds.width * 0.5 - side/2, y: label.bounds.height * 0.85) // 设置圆环的位置 
    button.strokeColor = UIColor.black.cgColor // 设置圆环边框的颜色 
    button.fillColor = UIColor.clear.cgColor // 设置圆环的填充颜色
    button.path = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: side, height: side)).cgPath // 设置路径
    button.lineWidth = 1.0 // 边框宽度
    button.opacity = 0.5 // 透明度
    label.layer.addSublayer(button) // 将圆环添加到label的layer上面 
    
    // 缩放动画
    let scale = CABasicAnimation(keyPath: "transform.scale") // 创建缩放动画
    scale.fromValue = 1.0 // 开始值
    scale.toValue = 0.67  // 结束值
    scale.duration = 2.0 // 动画时间
    scale.repeatCount = Float.infinity // 重复次数
    scale.autoreverses = true // 逆向运行动画
    button.add(scale, forKey: nil) // 为圆环添加动画

    }

写好上面这些代码后,我们在哪里调用呢? 别急,还记得上面为UILabel添加动画的那个方法吗?(animateText),只需要在else里面调用这个方法就行了。

func animateText(text: String) {
    if text.characters.count > 0 { 
        ...
        
    } else {
        // 结束Label动画,如果要做别的操作,在这里添加代码 
        // 添加几个就是几个圆环
        delay(0.1, task: {self.addButtonRing()})
        delay(1.2, task: {self.addButtonRing()})        delay(2.4, task: {self.addButtonRing()})
    }
}

现在让我们来看一下成果吧,见证奇迹的时候到了,哇咔咔。


效果图

我们还可以为它加一个imageView的遮罩,比如像这样, 最终效果见下图:

    let imageView = UIImageView(image: UIImage(named: "dog3"))
    imageView.center.x = label.bounds.width/2
    label.addSubview(imageView)
效果图

图片的颜色也发生了渐变。

至此,今天的内容就到这里了。合理的运用CAGradientLayer,还可以做很多有意思的小应用,等着聪明的你们去发掘。如果你喜欢这篇文章,就请献上你们的小星星吧~~。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 转载:http://www.jianshu.com/p/32fcadd12108 每个UIView有一个伙伴称为l...
    F麦子阅读 6,148评论 0 13
  • 每个UIView有一个伙伴称为layer,一个CALayer。UIView实际上并没有把自己画到屏幕上;它绘制本身...
    shenzhenboy阅读 3,081评论 0 17
  • >复杂的组织都是专门化的 >Catharine R. Stimpson 到目前为止,我们已经探讨过`CALayer...
    夜空下最亮的亮点阅读 995评论 0 2
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,091评论 5 13
  • 我爱过一个美丽的朋友,她如春天的风夏日的荷,她孤独起来有秋的寂寥,也不失冬的傲雪寒霜。多希望她生命中有一部...
    鲜研阅读 281评论 0 4