CoreGraphic框架解析 (十二)—— Shadows 和 Gloss (一)

版本記錄

版本號 時間
V1.0 2019.02.11 星期一

前言

quartz是一個通用的術語,用于描述在iOSMAC OS X 中整個媒體層用到的多種技術 包括圖形、動畫君旦、音頻、適配嘲碱。Quart 2D 是一組二維繪圖和渲染API金砍,Core Graphic會使用到這組APIQuartz Core專指Core Animation用到的動畫相關的庫麦锯、API和類恕稠。CoreGraphicsUIKit下的主要繪圖系統,頻繁的用于繪制自定義視圖扶欣。Core Graphics是高度集成于UIView和其他UIKit部分的鹅巍。Core Graphics數據結構和函數可以通過前綴CG來識別。在app中很多時候繪圖等操作我們要利用CoreGraphic框架宵蛀,它能繪制字符串昆著、圖形、漸變色等等术陶,是一個很強大的工具凑懂。感興趣的可以看我另外幾篇。
1. CoreGraphic框架解析(一)—— 基本概覽
2. CoreGraphic框架解析(二)—— 基本使用
3. CoreGraphic框架解析(三)—— 類波浪線的實現
4. CoreGraphic框架解析(四)—— 基本架構補充
5. CoreGraphic框架解析 (五)—— 基于CoreGraphic的一個簡單繪制示例 (一)
6. CoreGraphic框架解析 (六)—— 基于CoreGraphic的一個簡單繪制示例 (二)
7. CoreGraphic框架解析 (七)—— 基于CoreGraphic的一個簡單繪制示例 (三)
8. CoreGraphic框架解析 (八)—— 基于CoreGraphic的一個簡單繪制示例 (四)
9. CoreGraphic框架解析 (九)—— 一個簡單小游戲 (一)
10. CoreGraphic框架解析 (十)—— 一個簡單小游戲 (二)
11. CoreGraphic框架解析 (十一)—— 一個簡單小游戲 (三)

開始

首先看下寫作環(huán)境

Swift 4.2, iOS 12, Xcode 10

通過應用陰影和光澤(shadows and gloss)使您的UI元素脫穎而出梧宫。 陰影營造出一種深度感接谨,而光澤則讓您的元素閃耀摆碉。

在iOS 6之前,光澤(gloss)效果在iOS中很常見脓豪,從按鈕和條形圖到UIKit中的幾乎任何元素巷帝。 在iOS 7中,Apple將其設計方法改為更扁平的界面扫夜。 這并不意味著使用光澤效果是錯誤的或過時的楞泼! 了解如何創(chuàng)建它們仍然很重要。

Core Graphics使其變得簡單笤闯。

在本教程中堕阔,您將學習一個名為Cool Table的項目。 該項目本身涵蓋了許多關于Core Graphics的主題颗味,但在本教程中超陆,您將專注于如何在視圖上創(chuàng)建陰影和簡單的光澤效果。

首先浦马,打開已經下載好的項目时呀,并在Xcode中打開啟動項目并運行它。

您將看到一個由兩個部分組成的分組表晶默,每個部分都有一個標題和三行谨娜。 你在這里要做的所有工作都將在這些部分的標題視圖中,因此不必擔心行荤胁。


The Drawing Canvas

現在瞧预,該表通過tableView(_:titleForHeaderInSection :)顯示節(jié)標題,它不允許在標題中進行太多自定義仅政。 為了能夠自定義它垢油,您需要使用tableView(_:viewForHeaderInSection :)設置標頭。

值得了解的是圆丹,有兩種方法可以創(chuàng)建標題視圖:

  • 您可以僅使用代碼創(chuàng)建自定義視圖滩愁。
  • 您可以使用Interface Builder創(chuàng)建自定義視圖。

兩者都是不錯的選擇辫封,但在這里硝枉,你將采取第二種方法。 您將在Interface Builder中創(chuàng)建和自定義視圖倦微,并將其作為header view提供妻味。

1. Creating the Files

Project導航器中,使用Cocoa Touch Class模板創(chuàng)建一個新文件欣福。 將類命名為CustomHeader责球。 確保它是UIView的子類,語言是Swift。

創(chuàng)建空UIView子類后雏逾,創(chuàng)建名為CustomHeader.xib文件嘉裤。 這一次,不要在模板選擇中選擇Cocoa Touch Class栖博,而是在User Interface組中選擇View屑宠。

在新的XIB文件中,您將找到一個視圖仇让。 在Identity檢查器中典奉,將其類從UIView更改為CustomHeader,這是您剛剛創(chuàng)建的類丧叽。

現在您需要header來顯示section名稱秋柄。 請遵循以下三個步驟:

  • 1) 從View菜單中打開Library,然后將label拖到XIB文件內的視圖上蠢正。
  • 2) 為標簽創(chuàng)建所有四個約束,左右兩個點間距分別為4省店,頂部距離0嚣崭,底部距離10。
  • 3) 在“屬性”檢查器中懦傍,將其文本對齊方式設置為center雹舀。
  • 4) 再次選擇CustomHeader視圖。 在“屬性”檢查器中粗俱,將Simulated Metrics組中的SizeInferred更改為Freeform说榆。
  • 5) 在Size inspector中,將視圖的高度設置為50寸认。

接下來签财,在CustomHeader.swift中,為UILabeloutlet添加此行偏塞。 確保將其連接到XIB文件中唱蒸。

@IBOutlet public var titleLabel: UILabel!

2. Loading the View

下一步是從interface file加載視圖并將其提供給table view。 要完成此操作灸叼,請在outlet后面添加以下方法:

class func loadViewFromNib() -> CustomHeader? {
  let bundle = Bundle.main
  let nib = UINib(nibName: "CustomHeader", bundle: bundle)
  guard 
    let view = nib.instantiate(withOwner: CustomHeader())
      .first as? CustomHeader
    else {
      return nil
    }
  return view
}

loadViewFromNib()是一個為您創(chuàng)建并返回CustomHeader的類方法神汹。

接下來,在CoolTableViewController.swift中古今,在類的末尾添加此方法:

override func tableView(
  _ tableView: UITableView,
  viewForHeaderInSection section: Int
  ) -> UIView? {
  guard let customHeaderView = CustomHeader.loadViewFromNib()
    else { return nil }
  customHeaderView.titleLabel.text = self.tableView(
    tableView,
    titleForHeaderInSection: section)
  
  return customHeaderView
}

代碼按照上一步驟中的說明加載視圖屁魏,設置label的文本,并返回新視圖捉腥。

建立并運行氓拼。 您將看到剛剛使用白色背景創(chuàng)建的新header


Drawing the Masterpiece

現在你有了一個標題畫布,你已經準備好了有趣的部分披诗。 首先撬即,考慮一下你將要繪制的杰作中需要什么。

header分為兩個區(qū)域呈队。 在上圖中剥槐,有三點需要注意。

  • 帶有光澤的漸變色宪摧。
  • 彩色區(qū)域下方的一個小陰影粒竖。
  • 標題周圍的stroke line

陰影區(qū)域是10點几于。 這就是label下的底部約束為10的原因蕊苗。您知道完整標題的高度為50。因此沿彭,彩色區(qū)域為40朽砰。


Preparing the Header

為什么不通過賦予每種不同的顏色來直觀地定義這些區(qū)域? 您將為漸變區(qū)域指定紅色背景并使陰影區(qū)域變?yōu)榫G色喉刘。

CustomHeader.swift中瞧柔,在標題label聲明后面添加以下行:

@IBInspectable var coloredBoxHeight: CGFloat = 40

@IBInspectable值允許您直接從Interface Builder執(zhí)行盡可能多的UI自定義。

將任何數字聲明為常量或屬性而不是在代碼中分散許多數字是一種很好的做法睦裳。 大多數情況下造锅,幾天后查看自己的代碼時,您會忘記使用的具體數字廉邑。

CustomHeader的末尾添加此方法:

override func draw(_ rect: CGRect) {
    // 1:
    var coloredBoxRect = bounds
    coloredBoxRect.size.height = coloredBoxHeight
    
    var paperRect = bounds
    paperRect.origin.y += coloredBoxHeight
    paperRect.size.height = bounds.height - coloredBoxHeight
    
    // 2:
    let context = UIGraphicsGetCurrentContext()!
    
    context.setFillColor(UIColor.red.cgColor)
    context.fill(coloredBoxRect)
    
    context.setFillColor(UIColor.green.cgColor)
    context.fill(paperRect)
  }

UIViewdraw(_:)是放置任何您想要用來更改自定義視圖外觀的自定義繪圖代碼的位置哥蔚。 默認繪制方法不執(zhí)行任何操作。 因此蛛蒙,請確保您重寫糙箍。 這里有兩個步驟:

  • 1) 計算要著色的兩個矩形。 第一個是具有漸變的區(qū)域宇驾。 第二個是陰影區(qū)域倍靡。 兩者都是基于您之前定義的coloredBoxHeight計算的。
  • 2) 獲取當前的Core Graphics上下文并繪制兩個彩色矩形课舍。

現在塌西,直接從Attributes inspectorCustomHeader.xib中標題的label文本顏色更改為白色。

建立并運行筝尾。 你應該看到你的彩色標題捡需。


Drawing Drop Shadows

現在明確定義了矩形,添加陰影筹淫。 在CustomHeader.swift中站辉,在coloredBoxHeight之后添加這兩個變量:

var lightColor = UIColor(red: 105/255.0, green: 179/255.0, blue: 216/255.0, alpha: 1)
var darkColor = UIColor(red: 21/255.0, green: 92/255.0, blue: 136/255.0, alpha: 1)

接下來,在draw(_ :)方法中,從方法的底部刪除以下四行饰剥。

context.setFillColor(UIColor.red.cgColor)
context.fill(coloredBoxRect)
    
context.setFillColor(UIColor.green.cgColor)
context.fill(paperRect)

然后添加下面這些行:

// 1:
let shadowColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 0.5)
// 2:
context.saveGState()  
// 3:
context.setShadow(
  offset: CGSize(width: 0, height: 2), 
  blur: 3.0,
  color: shadowColor.cgColor) 
// 4:
context.setFillColor(lightColor.cgColor)
context.fill(coloredBoxRect) 
// 5:
context.restoreGState()

這就是你畫陰影的方式殊霞! 以下是上述代碼的含義,一步一步看一下:

  • 1) 將陰影定義為灰色汰蓉,透明度為50%绷蹲。
  • 2) 保存當前圖形狀態(tài),以便您可以應用所需的任何配置更改顾孽,并在完成后返回到此狀態(tài)祝钢。
  • 3) 為要繪制的任何內容設置陰影配置。
  • 4) 畫出彩色的盒子若厚。 如果沒有這個拦英,屏幕上就不會有陰影。
  • 5) 返回上面保存的圖形配置测秸。

最后疤估,在CoolTableViewController.swift中,在return之前的tableView(_:viewForHeaderInSection :)的末尾添加以下行:

if section == 1 {
  customHeaderView.lightColor = UIColor(
    red: 147/255.0,
    green: 105/255.0,
    blue: 216/255.0,
    alpha: 1)
  customHeaderView.darkColor = UIColor(
    red: 72/255.0,
    green: 22/255.0,
    blue: 137/255.0,
    alpha: 1)
}

這是為第二個table section顯示不同的顏色霎冯。 darkColor尚未使用做裙,所以不要擔心。

建立并運行肃晚。 您應該看到上次運行應用程序時的巨大改進。 標題現在看起來更好仔戈,對吧关串? 接下來,您將添加光澤效果监徘。


Adding a Gloss Effect

應用光澤效果的方法不止一種晋修。 Matt GallagherMichael Heyeck解釋了更難的方法,但在這里凰盔,你將學習一種簡單的方法墓卦。

為簡單起見,通過應用漸變alpha蒙版來實現光澤效果的近似是現在足夠好的方法户敬。

專業(yè)提示:這是一種常用的方法落剪,為什么不把它放在一個單獨的文件中,以便在以后的項目中輕松訪問尿庐?Extensions.swift是該作業(yè)的文件忠怖。 它有一些方便的擴展,使事情變得更容易抄瑟。

CGContext擴展的末尾凡泣,添加以下方法:

func drawGlossAndGradient(rect: CGRect, startColor: UIColor, endColor: UIColor) {
  // 1:
  drawLinearGradient(rect: rect, startColor: startColor, endColor: endColor)
  // 2:
  let glossColor1 = UIColor.white.withAlphaComponent(0.35)
  let glossColor2 = UIColor.white.withAlphaComponent(0.1)
  // 3:
  var topHalf = rect
  topHalf.size.height /= 2
  // 4:
  drawLinearGradient(rect: topHalf, startColor: glossColor1, endColor: glossColor2)
}

以下是上面代碼的作用:

  • 1) 從示例項目中調用擴展文件中的另一個方法,該方法在矩形中繪制雙色漸變。
  • 2) 定義兩種白色光澤顏色鞋拟。
  • 3) 計算將具有白色漸變或光澤的矩形骂维。 此矩形是彩色漸變區(qū)域的一半。
  • 4) 在較小的矩形中繪制白色漸變贺纲。

CustomHeader.swift中航闺,在draw(_:)結束時,添加以下行:

context.drawGlossAndGradient(
  rect: coloredBoxRect,
  startColor: lightColor,
  endColor: darkColor)

構建并運行哮笆。 你會看到一個漂亮的標題来颤,帶有漸變色和光澤效果。

你需要的最后一件事是在標題的彩色區(qū)域周圍進行stroke稠肘。 在剛添加的行之后福铅,添加以下行:

context.setStrokeColor(darkColor.cgColor)
context.setLineWidth(1)
context.stroke(coloredBoxRect.rectFor1PxStroke())

建立并運行。 注意你想要的較暗的stroke项阴。

CGContext有很多有趣的繪圖工具滑黔,可用于繪制路徑,線條环揽,形狀略荡,文本和圖像。 值得查看developer documentation并進行實驗歉胶。

后記

本篇主要講述了Shadows 和 Gloss汛兜,感興趣的給個贊或者關注~~~

?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市通今,隨后出現的幾起案子粥谬,更是在濱河造成了極大的恐慌,老刑警劉巖辫塌,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漏策,死亡現場離奇詭異,居然都是意外死亡臼氨,警方通過查閱死者的電腦和手機掺喻,發(fā)現死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來储矩,“玉大人感耙,你說我怎么就攤上這事〕炙恚” “怎么了抑月?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長舆蝴。 經常有香客問我谦絮,道長题诵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任层皱,我火速辦了婚禮性锭,結果婚禮上,老公的妹妹穿的比我還像新娘叫胖。我一直安慰自己草冈,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布瓮增。 她就那樣靜靜地躺著怎棱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绷跑。 梳的紋絲不亂的頭發(fā)上拳恋,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音砸捏,去河邊找鬼谬运。 笑死,一個胖子當著我的面吹牛垦藏,可吹牛的內容都是我干的梆暖。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼掂骏,長吁一口氣:“原來是場噩夢啊……” “哼轰驳!你這毒婦竟也來了?” 一聲冷哼從身側響起弟灼,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤滑废,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后袜爪,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡薛闪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年辛馆,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豁延。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡昙篙,死狀恐怖,靈堂內的尸體忽然破棺而出诱咏,到底是詐尸還是另有隱情苔可,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布袋狞,位于F島的核電站焚辅,受9級特大地震影響映屋,放射性物質發(fā)生泄漏。R本人自食惡果不足惜同蜻,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一棚点、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧湾蔓,春花似錦瘫析、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至桃序,卻和暖如春杖虾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背葡缰。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工亏掀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人泛释。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓滤愕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親怜校。 傳聞我的和親對象是個殘疾皇子间影,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內容