四.iOS核心动画 - 图层的视觉效果

引言

在前几篇博客中我们讨论了图层的frame,bounds,position以及让图层加载图片。但是图层事实上不仅可以显示图片,或者规则的矩形块,它还有一系列内建的特性来创建美丽优雅的页面元素。在这篇博客中我们就来探索一下CALayer的视觉效果。

视觉效果

图层的一些基础视觉效果其实在我们的日常开发过程中也经常会用到,比如圆角,边框,阴影,还有一些不常用的效果比如蒙版,下面我们就来一一讨论一下。

图层圆角

近些年圆角矩形几乎成为了主流的审美特性,不管是图标,还是页面元素,甚至文本输入框也都是按照圆角矩形来设计的。

CALayer有一个叫做cornerRadius的属性来控制着图层的圆角曲率,它是一个浮点型默认为0也就是直角。通过修改它为一个大于0的值,可以实现CALayer的圆角,默认情况下这个值只影响本图层的背景颜色,而不影响图层的背景图片或者是子图层,不过如果把maskesToBounds设置成为YES的话,图层里面的所有东西都会被截取。

未设置masksToBounds属性:

        let whiteLayer = CALayer()whiteLayer.backgroundColor = UIColor.white.cgColorwhiteLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)whiteLayer.position = self.view.centerwhiteLayer.cornerRadius = 20.0self.view.layer.addSublayer(whiteLayer)let yellowLayer = CALayer()yellowLayer.backgroundColor = UIColor.yellow.cgColoryellowLayer.frame = CGRect(x: -50, y: -50, width: 100, height: 100)whiteLayer.addSublayer(yellowLayer)

效果如下:

增加masksToBounds属性为true:

whiteLayer.masksToBounds = true

效果如下:

图层边框

CALayer的两个常用属性borderWidth和borderColor,两个属性共同决定了图层边框的样式。边框沿着图层的bounds往内绘制,同时也包含图层的圆角。

borderWidth属性定义了边框的宽度,是浮点数。

borderColor属性定义了边框的颜色默认是黑色,类型为CGColorRef。

我们使用上面的代码为图层添加边框 - 未设置masksToBounds:

        let whiteLayer = CALayer()whiteLayer.backgroundColor = UIColor.white.cgColorwhiteLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)whiteLayer.position = self.view.centerwhiteLayer.cornerRadius = 20.0whiteLayer.borderWidth = 2.0whiteLayer.borderColor = UIColor.blue.cgColorself.view.layer.addSublayer(whiteLayer)let yellowLayer = CALayer()yellowLayer.backgroundColor = UIColor.yellow.cgColoryellowLayer.frame = CGRect(x: -50, y: -50, width: 100, height: 100)whiteLayer.addSublayer(yellowLayer)

效果如下:

我们发现当设置边框时并不会把寄宿图或者是子图层的形状计算出来,而是沿着图层的边界进行绘制的。

图层阴影

iOS中阴影也是一个十分常见的特性,关于图层阴影的设置涉及到多个属性共同作用。

shadowOpacity:修改这个属性为一个大于0的值,阴影就可以显示在任意图层之下。它是一个介于0和1之间的浮点数。

shadowColor:控制阴影的颜色,它的类型也是CGColorRef,默认为黑色。

shadowOffset:控制阴影的方向和距离,它是一个CGSize值,宽度控制这个阴影的横向位移,高度控制阴影的纵向位移。默认值为{0,-3}向上偏移3。

shadowRadius:控制阴影的模糊程度,当设置为0的时候阴影就和图层一样有一个非常确定的边界线,当值越大边界线看上去就会越模糊和自然。

我们来创建一个橙色的图层并为它添加阴影效果,代码如下:

        self.view.backgroundColor = .whitelet originLayer = CALayer()originLayer.backgroundColor = UIColor.orange.cgColororiginLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)originLayer.position = self.view.centerself.view.layer.addSublayer(originLayer)originLayer.shadowOpacity = 0.7originLayer.shadowOffset = CGSize(width: 0, height: 3)originLayer.shadowRadius = 3originLayer.shadowColor = UIColor.black.cgColor

效果如下:

shadowPath:当我们给图层设置阴影属性的时候发现还有一个属性我们没有介绍到shadowPath。

这就意味着阴影的形状我们可以随意绘制,shadowPath是一个CGPathRef类型(一个指向CGPath的指针),CGPath是一个Core Graphics对象,用来指定任意的一个矢量图形。

来修改一下上面的代码为图层添加一个圆形的阴影,代码如下:

        let originLayer = CALayer()originLayer.backgroundColor = UIColor.orange.cgColororiginLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)originLayer.position = self.view.centerself.view.layer.addSublayer(originLayer)originLayer.shadowOpacity = 0.7originLayer.shadowOffset = CGSize(width: 0, height: 3)originLayer.shadowRadius = 3originLayer.shadowColor = UIColor.black.cgColorlet circlePath = CGPath(roundedRect: CGRect(x: -25, y: -25, width: 250, height: 250), cornerWidth: 250, cornerHeight: 250, transform: nil)originLayer.shadowPath = circlePath

效果如下:

图层的阴影另外还有两个特殊的地方,它和图层的边框不同,阴影继承自图层内容的外形,而不是图层的边界和角半径。为了计算出阴影的形状,Core Animation会将寄宿图考虑在内,包括子视图。

下面我们来加载一个图像,代码如下:

        let originLayer = CALayer()originLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)originLayer.position = self.view.centerself.view.layer.addSublayer(originLayer)originLayer.shadowOpacity = 0.7originLayer.shadowOffset = CGSize(width: 0, height: 3)originLayer.shadowRadius = 3originLayer.shadowColor = UIColor.black.cgColororiginLayer.contents = UIImage(named: "icon_dynamic_like_selected")?.cgImageoriginLayer.contentsScale = UIScreen.main.scale

效果如下,Core Animation为我们创建了一个心形的阴影因为图层的内容为心形:

图层阴影的另外一个特殊的地方在于当我们设置masksToBounds的属性为true之后,超出图层部分的阴影会被裁剪掉。

这样给圆角矩形设置阴影的时候就需要花点小心思,比如使用两个相同的图层其中一个设置阴影。

图层蒙版

还有的时候我们希望展示的内容不是在一个矩形也不是圆角矩形,比如说你想显示一个星星,或者显示一个镂空的文字。这个时候我们可以使用图层蒙版来是现实。

CALayer有一个mask属性,这个属性本身就是CALayer类型,它类似一个子图层,它相对父图层进行布局,但是它却不是一个普通的子图层,mask图层定义了父图层的部分可见区域。

mask图层的color属性是无关紧要的,真正重要的是图层的轮廓。mask属性就像一个模型切割机,mask图层实心的部分也就是不透明的部分会被保留下来。

如果mask图层比父图层小,那么只有在mask图层里面的内容才是它关心的,除此之外的一切都会被隐藏起来。

下面我们来创建一个例子:

​​​​​​​

当我们设置为子图层的时候显示效果如下:

当我们设置为mask的时候代码如下:

        // 背景let bgLayer = CALayer()bgLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 200)bgLayer.position = self.view.centerbgLayer.contents = UIImage(named: "random_dynamic_pic_0")?.cgImagebgLayer.contentsScale = UIScreen.main.scaleself.view.layer.addSublayer(bgLayer)// 蒙版let maskLayer = CALayer()maskLayer.frame = CGRect(x: 70, y: 70, width: 50, height: 50)maskLayer.contents = UIImage(named: "icon_dynamic_like_selected")?.cgImagemaskLayer.contentsScale = UIScreen.main.scalebgLayer.mask = maskLayer

效果如下:

图层的拉伸过滤方式

最后我们再来谈一下图层的minificationFilter和magnificationFilter属性,这两个属性我们不常用,他们定义了图片在被拉伸或者被压缩时采用的拉伸过滤方式。

CALayer提供了三种拉伸过滤方式:

  • CALayerContentsFilter.linear
  • CALayerContentsFilter.nearest
  • CALayerContentsFilter.trilinear

通常来讲这两个属性的默认值都是.linear,既采用双线性滤波算法过滤器进行压缩和拉伸,大多数情况下都表现良好,双线性滤波算法通过对个像素取样来生成最终的值,会得到一个还不错的拉伸效果,但是当放大倍数比较大的时候就模糊不清了。

.trailinear和.linear非常相似,大部分情况下二者都看不出来有啥区别。相对双线性滤波算法,三线性滤波算法存储了多个大小情况下的图片,并三维取样,同时结合大图和小图的存储进而得到最后的结果。

.nearest是一种比较武断的方案,这个算法就是取样最近的单像素点,而不管其它的颜色,这样做非常快。但是最明显的效果就是会使得压缩图片更糟,放大之后也会有明显的马赛克,但是它也有适用的地方,比如对于没有斜线的小图来说最近过滤算法就要好很多。

下面举两个例子,一个带斜线的小图,图片的原始大小是50*30,我们分别使用三种算法来进行放大3倍。

代码如下:

       // 原始比例let orginLayer = CALayer()orginLayer.frame = CGRect(x: 70, y: 100, width: 50, height: 30)orginLayer.contents = UIImage(named: "Property 1=ktv")?.cgImageorginLayer.contentsScale = UIScreen.main.scaleself.view.layer.addSublayer(orginLayer)// 放大3倍 - 双线性滤波算法let magLayer = CALayer()magLayer.frame = CGRect(x: 70, y: 200, width: 50 * 3, height: 30 * 3)magLayer.contents = UIImage(named: "Property 1=ktv")?.cgImagemagLayer.contentsScale = UIScreen.main.scalemagLayer.magnificationFilter = .linearself.view.layer.addSublayer(magLayer)// 放大3倍 - 三线性滤波算法let magLayer1 = CALayer()magLayer1.frame = CGRect(x: 70, y: 300, width: 50 * 3, height: 30 * 3)magLayer1.contents = UIImage(named: "Property 1=ktv")?.cgImagemagLayer1.contentsScale = UIScreen.main.scalemagLayer1.magnificationFilter = .trilinearself.view.layer.addSublayer(magLayer1)// 放大3倍 - 最近邻滤波算法let magLayer2 = CALayer()magLayer2.frame = CGRect(x: 70, y: 400, width: 50 * 3, height: 30 * 3)magLayer2.contents = UIImage(named: "Property 1=ktv")?.cgImagemagLayer2.contentsScale = UIScreen.main.scalemagLayer2.magnificationFilter = .nearestself.view.layer.addSublayer(magLayer2)

效果如下:

我们来更换一张不带斜边的图片,效果如下:

总的来说呢,相对于比较小的图或者是差异特别明显,极少斜线的大图,最近过滤算法会保留这种差异明显的特性以呈现更好的结果。

但是对于大多数图图尤其是有很多斜线或者曲线的图片来说,双线性和三线形滤波算法的结果更好些,而最近过滤算法会极差。

换句话说,线性过滤保留了形状,而最近过滤保留了像素差异。

总结

本篇博客介绍了一些使用代码可以实现的图层的视觉特效,比如阴影,蒙版,圆角。又介绍了一些拉伸过滤的方案。

下篇博客我们开始研究图层的变化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/37566.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

转化分析|一位数据分析师的实验田复盘

花3个月时间,吭哧吭哧写了80页草稿的《投资——1. 知己知彼》,发布之前豪言壮语“2000阅读量”,到现在累计72,真是piapia打脸!心态那个崩啊!! 朋友们吐槽内容太长、定位不明确、分析深度不够&am…

手持式雷达流速仪的工作原理

TH-LS5手持式雷达流速仪基于雷达技术和多普勒效应进行工作。它发射一束微波信号到水体表面,当信号遇到水流时,会发生多普勒频移。发射器发出的高频电磁波信号(通常是微波信号)遇到流体后,部分信号会被反射回来。接收器接收到反射回来的信号&a…

开发一套java语言的智能导诊需要什么技术?java+ springboot+ mysql+ IDEA互联网智能3D导诊系统源码

开发一套java语言的智能导诊需要什么技术?java springboot mysql IDEA互联网智能3D导诊系统源码 医院导诊系统是一种基于互联网和3D人体的智能化服务系统,旨在为患者提供精准、便捷的医院就诊咨询服务。该系统整合了医院的各种医疗服务资;智慧…

【机器学习】机器学习与医疗健康在疾病预测中的融合应用与性能优化新探索

文章目录 引言第一章:机器学习在医疗健康中的应用1.1 数据预处理1.1.1 数据清洗1.1.2 数据归一化1.1.3 特征工程 1.2 模型选择1.2.1 逻辑回归1.2.2 决策树1.2.3 随机森林1.2.4 支持向量机1.2.5 神经网络 1.3 模型训练1.3.1 梯度下降1.3.2 随机梯度下降1.3.3 Adam优化…

【你也能从零基础学会网站开发】(了解)关系型数据库的基本架构体系结构与概念理解

🚀 个人主页 极客小俊 ✍🏻 作者简介:程序猿、设计师、技术分享 🐋 希望大家多多支持, 我们一起学习和进步! 🏅 欢迎评论 ❤️点赞💬评论 📂收藏 📂加关注 关系型数据库的…

【第五节】C/C++数据结构之图

目录 一、图的基本概念 1.1 图的定义 1.2 图的其他术语概念 二、图的存储结构 2.1 邻接矩阵 2.2 邻接表 三、图的遍历 3.1 广度优先遍历 3.2 深度优先遍历 四、最小生成树 4.1 最小生成树获取策略 4.2 Kruskal算法 4.3 Prim算法 五、最短路径问题 5.1 Dijkstra算…

INFINI Easysearch尝鲜Hands on

INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 的目标是提供一个自主可控的轻量级的 Elasticsearch 可替代版本,并继续完善和支持更多的企业级功能。 与 Elasticsearch 相比,Easysear…

熊猫烧香是什么?

熊猫烧香(Worm.WhBoy.cw)是一种由李俊制作的电脑病毒,于2006年底至2007年初在互联网上大规模爆发。这个病毒因其感染后的系统可执行文件图标会变成熊猫举着三根香的模样而得名。熊猫烧香病毒具有自动传播、自动感染硬盘的能力,以及…

vue 组件下 img 标签动态传入不展示

效果 解决办法&#xff1a; require() <titleComponent:title"业务工作概览":src"require(/assets/imgs/evaluation/overviewStatistics.png)"></titleComponent> 效果&#xff1a;

Github 上 Star 数最多的大模型应用基础服务 Dify 深度解读(一)

背景介绍 接触过大模型应用开发的研发同学应该都或多或少地听过 Dify 这个大模型应用基础服务&#xff0c;这个项目自从 2023 年上线以来&#xff0c;截止目前&#xff08;2024-6&#xff09;已经获得了 35k 多的 star&#xff0c;是目前大模型应用基础服务中最热门的项目之一…

从0到1搭建微服务框架

目录 1.技术栈&#xff1a; 2.模块介绍: 3.关键代码讲解 3.1基础公共模块(common)依赖&#xff1a; 3.3授权模块(auth)依赖: 3.4授权模块核心配置类(AuthrizatonConfig): 3.4 SecurityConfig.java 3.5 bootstrap的核心配置文件(其他服务配置类似这个)&#xff1a; 3.6n…

防爆巡检终端在石化工厂安全保障中的应用

防爆巡检终端在石化工厂安全保障中的应用是广泛而关键的&#xff0c;其设计旨在确保在易燃易爆环境中进行安全、有效的巡检工作。以下是防爆巡检终端在石化工厂安全保障中的详细应用描述&#xff1a; 1. 环境监测与预警 防爆巡检终端配备了各种传感器&#xff0c;能够实时监测…

网银U盾多又乱?后悔没早点用USB Server远程连接管理!

一、引言 网银服务已成为企业日常运营中不可或缺的一部分。但随着企业规模的扩大和业务的增多&#xff0c;网银U盾的数量也随之激增&#xff0c;又多又乱&#xff0c;只能频繁插拔、分散管理&#xff0c;不仅效率低下&#xff0c;而且存在严重的安全隐患。 事实上&#xff0…

ADS131A04硬件设计与软件调试

一、IC基本信息 ADS131A0x 双通道或四通道 24 位 128kSPS 同步采样 Δ-Σ ADC •双通道或四通道同步采样差分输入 • 数据速率&#xff1a;高达 128kSPS • 高性能&#xff1a; – 单通道精度&#xff1a;在 10,000:1 动态范围内优于 0.1% – 有效分辨率&#xff1a;20.6位…

SpringCloud-服务网关-Gateway

1.服务网关在微服务中的应用 (1)对外提供服务的难题分析&#xff1a; 微服务架构下的应用系统体系很庞大&#xff0c;光是需要独立部署的基础组件就有注册中心、配置中心和服务总线、Turbine异常聚合和监控大盘、调用链追踪器和链路聚合&#xff0c;还有Kaka和MQ之类的中间件&…

海思NNIE部署yolov5-shufflenet

1.简要说明 由于NNIE上transpose支持的顺序是固定的,shufflenet那种x=torch.transpose(x,1,2).contiguous() 的操作一般是不支持的。需要进行调整。 2.使用工程以及修改 使用的是开源工程:GitHub - Lufei-github/shufflev2-yolov5: shufflev2-yolov5:lighter, faster and ea…

玛格家居从深交所转板北交所:营收净利润连年下滑,销售费用大增

《港湾商业观察》施子夫 近日&#xff0c;玛格家居股份有限公司&#xff08;以下简称&#xff0c;玛格家居&#xff09;发布公告&#xff0c;重庆证监局已经受理其北交所上市的备案申请&#xff0c;辅导机构为国泰君安证券。 公开信息显示&#xff0c;2022年1月&#xff0c;玛…

基于STM32的智能电池管理系统

目录 引言环境准备智能电池管理系统基础代码实现&#xff1a;实现智能电池管理系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统实现4.4 用户界面与数据可视化应用场景&#xff1a;电池管理与优化问题解决方案与优化收尾与总结 1. 引言 智能电池管理系统&#xff08;Ba…

【昇思25天学习打卡营打卡指南-第十三天】ShuffleNet图像分类

ShuffleNet图像分类 ShuffleNet网络介绍 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;所以模型的设计目标就是利用有限的计算资源来达到最好的模型精度。ShuffleNetV1的设计核心是引入了两种操…

骁龙相机拍照流程分析

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 1.deliverInputEvent 拍照点击事件处理 2.submitRequestList Camera 提交拍照请求 3.createCaptureRequest 拍照请求帧数 骁龙相机通过binder 数据传输…