Swift

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

2017-11-20  本文已影响473人  Mr_Victory

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

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

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

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上面。下图是显示效果

// 设置渐变色(这里需要传递一个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,还可以做很多有意思的小应用,等着聪明的你们去发掘。如果你喜欢这篇文章,就请献上你们的小星星吧~~。
上一篇下一篇

猜你喜欢

热点阅读