四.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.pswp.cn/web/37566.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37566.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37566.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java筆記(29)——動態代理(工廠模式)【示例】

文章目錄 動態代理(工廠模式)接口類實體類代理類測試類 動態代理(工廠模式) 接口類 package com.itchen.proxytest;public interface Star {public abstract String sing(String name);public abstract void dance(); }實體類 …

轉化分析|一位數據分析師的實驗田復盤

花3個月時間,吭哧吭哧寫了80頁草稿的《投資——1. 知己知彼》,發布之前豪言壯語“2000閱讀量”,到現在累計72,真是piapia打臉!心態那個崩啊!! 朋友們吐槽內容太長、定位不明確、分析深度不夠&am…

手持式雷達流速儀的工作原理

TH-LS5手持式雷達流速儀基于雷達技術和多普勒效應進行工作。它發射一束微波信號到水體表面,當信號遇到水流時,會發生多普勒頻移。發射器發出的高頻電磁波信號(通常是微波信號)遇到流體后,部分信號會被反射回來。接收器接收到反射回來的信號&a…

開發一套java語言的智能導診需要什么技術?java+ springboot+ mysql+ IDEA互聯網智能3D導診系統源碼

開發一套java語言的智能導診需要什么技術?java springboot mysql IDEA互聯網智能3D導診系統源碼 醫院導診系統是一種基于互聯網和3D人體的智能化服務系統,旨在為患者提供精準、便捷的醫院就診咨詢服務。該系統整合了醫院的各種醫療服務資;智慧…

android gradle開發與應用(-)基礎

Gradle 是一個強大的自動化構建工具,廣泛用于多種編程語言和平臺,尤其是在 Android 應用開發中。Android Studio,作為官方的 Android 開發環境,使用 Gradle 作為其構建系統。了解 Gradle 的基礎對于有效地管理和構建 Android 項目…

【機器學習】機器學習與醫療健康在疾病預測中的融合應用與性能優化新探索

文章目錄 引言第一章:機器學習在醫療健康中的應用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年初在互聯網上大規模爆發。這個病毒因其感染后的系統可執行文件圖標會變成熊貓舉著三根香的模樣而得名。熊貓燒香病毒具有自動傳播、自動感染硬盤的能力,以及…

上海市計算機學會競賽平臺2023年5月月賽丙組最大子陣和

題目描述 給定 𝑛𝑛nn 個整數組成一個方陣 𝑎𝑖,𝑗ai,j?,請找一個 𝑘𝑘kk 的子方陣,使得子方陣內的數字之和達到最大,輸出這個最大值。 輸入格式 第一行&…

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;是目前大模型應用基礎服務中最熱門的項目之一…

ss命令詳細使用講解文章

ss 命令作為 iproute2 軟件包的一部分&#xff0c;是Socket Statistics的縮寫&#xff0c;也稱為IPC&#xff08;Inter-process Communication&#xff09;套接字統計 ss命令用于顯示sockets&#xff08;套接字&#xff09;的狀態。與netstat類似&#xff0c;但它通常提供更詳…

WebKit 簡介及工作流程探秘

在探索現代互聯網世界的奧秘時&#xff0c;瀏覽器引擎是不可或缺的一環&#xff0c;而 WebKit 正是其中的佼佼者。WebKit&#xff0c;這個開源的瀏覽器渲染引擎&#xff0c;以其卓越的性能和廣泛的支持度&#xff0c;成為了 Safari、早期的 Chrome 以及其他眾多瀏覽器的核心。本…

【筆試記錄】華為 | 20230823 | cpp

獲取連通的相鄰節點列表 題目描述 在網元內&#xff0c;存在了 N 個轉發節點&#xff0c;每個轉發節點有自己唯一的標識 TB 且每個節點有 M 個端口&#xff0c;節點間通過端口進行報文通訊。出于業務隔離的需求&#xff0c;服務器內的端口被劃分為多個通訊平面(用 VLAN 隔離&…

取消lfs, 使用原始文件上傳的辦法

查詢當前倉庫使用lfs的文件&#xff0c;然后刪除 git lfs ls-files 刪除lfs文件后&#xff0c;提交commit git add . git commit -m"remove lfs file" 查詢本地lfs配置 git config --local --list 重置本地lfs配置 git config --unset filter.lfs.smudgegit co…

從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…