版本記錄
| 版本號(hào) | 時(shí)間 |
|---|---|
| V1.0 | 2019.02.11 星期一 |
前言
quartz是一個(gè)通用的術(shù)語(yǔ),用于描述在iOS和MAC OS X中整個(gè)媒體層用到的多種技術(shù) 包括圖形、動(dòng)畫(huà)、音頻、適配。Quart 2D是一組二維繪圖和渲染API,Core Graphic會(huì)使用到這組API,Quartz Core專(zhuān)指Core Animation用到的動(dòng)畫(huà)相關(guān)的庫(kù)、API和類(lèi)。CoreGraphics是UIKit下的主要繪圖系統(tǒng),頻繁的用于繪制自定義視圖。Core Graphics是高度集成于UIView和其他UIKit部分的。Core Graphics數(shù)據(jù)結(jié)構(gòu)和函數(shù)可以通過(guò)前綴CG來(lái)識(shí)別。在app中很多時(shí)候繪圖等操作我們要利用CoreGraphic框架,它能繪制字符串、圖形、漸變色等等,是一個(gè)很強(qiáng)大的工具。感興趣的可以看我另外幾篇。
1. CoreGraphic框架解析(一)—— 基本概覽
2. CoreGraphic框架解析(二)—— 基本使用
3. CoreGraphic框架解析(三)—— 類(lèi)波浪線的實(shí)現(xiàn)
4. CoreGraphic框架解析(四)—— 基本架構(gòu)補(bǔ)充
5. CoreGraphic框架解析 (五)—— 基于CoreGraphic的一個(gè)簡(jiǎn)單繪制示例 (一)
6. CoreGraphic框架解析 (六)—— 基于CoreGraphic的一個(gè)簡(jiǎn)單繪制示例 (二)
7. CoreGraphic框架解析 (七)—— 基于CoreGraphic的一個(gè)簡(jiǎn)單繪制示例 (三)
8. CoreGraphic框架解析 (八)—— 基于CoreGraphic的一個(gè)簡(jiǎn)單繪制示例 (四)
9. CoreGraphic框架解析 (九)—— 一個(gè)簡(jiǎn)單小游戲 (一)
10. CoreGraphic框架解析 (十)—— 一個(gè)簡(jiǎn)單小游戲 (二)
11. CoreGraphic框架解析 (十一)—— 一個(gè)簡(jiǎn)單小游戲 (三)
開(kāi)始
首先看下寫(xiě)作環(huán)境
Swift 4.2, iOS 12, Xcode 10
通過(guò)應(yīng)用陰影和光澤(shadows and gloss)使您的UI元素脫穎而出。 陰影營(yíng)造出一種深度感,而光澤則讓您的元素閃耀。
在iOS 6之前,光澤(gloss)效果在iOS中很常見(jiàn),從按鈕和條形圖到UIKit中的幾乎任何元素。 在iOS 7中,Apple將其設(shè)計(jì)方法改為更扁平的界面。 這并不意味著使用光澤效果是錯(cuò)誤的或過(guò)時(shí)的! 了解如何創(chuàng)建它們?nèi)匀缓苤匾?/p>
Core Graphics使其變得簡(jiǎn)單。
在本教程中,您將學(xué)習(xí)一個(gè)名為Cool Table的項(xiàng)目。 該項(xiàng)目本身涵蓋了許多關(guān)于Core Graphics的主題,但在本教程中,您將專(zhuān)注于如何在視圖上創(chuàng)建陰影和簡(jiǎn)單的光澤效果。
首先,打開(kāi)已經(jīng)下載好的項(xiàng)目,并在Xcode中打開(kāi)啟動(dòng)項(xiàng)目并運(yùn)行它。

您將看到一個(gè)由兩個(gè)部分組成的分組表,每個(gè)部分都有一個(gè)標(biāo)題和三行。 你在這里要做的所有工作都將在這些部分的標(biāo)題視圖中,因此不必?fù)?dān)心行。
The Drawing Canvas
現(xiàn)在,該表通過(guò)tableView(_:titleForHeaderInSection :)顯示節(jié)標(biāo)題,它不允許在標(biāo)題中進(jìn)行太多自定義。 為了能夠自定義它,您需要使用tableView(_:viewForHeaderInSection :)設(shè)置標(biāo)頭。
值得了解的是,有兩種方法可以創(chuàng)建標(biāo)題視圖:
- 您可以僅使用代碼創(chuàng)建自定義視圖。
- 您可以使用
Interface Builder創(chuàng)建自定義視圖。
兩者都是不錯(cuò)的選擇,但在這里,你將采取第二種方法。 您將在Interface Builder中創(chuàng)建和自定義視圖,并將其作為header view提供。
1. Creating the Files
在Project導(dǎo)航器中,使用Cocoa Touch Class模板創(chuàng)建一個(gè)新文件。 將類(lèi)命名為CustomHeader。 確保它是UIView的子類(lèi),語(yǔ)言是Swift。

創(chuàng)建空UIView子類(lèi)后,創(chuàng)建名為CustomHeader的.xib文件。 這一次,不要在模板選擇中選擇Cocoa Touch Class,而是在User Interface組中選擇View。
在新的XIB文件中,您將找到一個(gè)視圖。 在Identity檢查器中,將其類(lèi)從UIView更改為CustomHeader,這是您剛剛創(chuàng)建的類(lèi)。

現(xiàn)在您需要header來(lái)顯示section名稱(chēng)。 請(qǐng)遵循以下三個(gè)步驟:
- 1) 從
View菜單中打開(kāi)Library,然后將label拖到XIB文件內(nèi)的視圖上。 - 2) 為標(biāo)簽創(chuàng)建所有四個(gè)約束,左右兩個(gè)點(diǎn)間距分別為4,頂部距離0,底部距離10。
- 3) 在“屬性”檢查器中,將其文本對(duì)齊方式設(shè)置為
center。 - 4) 再次選擇
CustomHeader視圖。 在“屬性”檢查器中,將Simulated Metrics組中的Size從Inferred更改為Freeform。 - 5) 在
Size inspector中,將視圖的高度設(shè)置為50。
接下來(lái),在CustomHeader.swift中,為UILabel 的outlet添加此行。 確保將其連接到XIB文件中。
@IBOutlet public var titleLabel: UILabel!
2. Loading the View
下一步是從interface file加載視圖并將其提供給table view。 要完成此操作,請(qǐng)?jiān)?code>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()是一個(gè)為您創(chuàng)建并返回CustomHeader的類(lèi)方法。
接下來(lái),在CoolTableViewController.swift中,在類(lèi)的末尾添加此方法:
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
}
代碼按照上一步驟中的說(shuō)明加載視圖,設(shè)置label的文本,并返回新視圖。
建立并運(yùn)行。 您將看到剛剛使用白色背景創(chuàng)建的新header。

Drawing the Masterpiece
現(xiàn)在你有了一個(gè)標(biāo)題畫(huà)布,你已經(jīng)準(zhǔn)備好了有趣的部分。 首先,考慮一下你將要繪制的杰作中需要什么。

header分為兩個(gè)區(qū)域。 在上圖中,有三點(diǎn)需要注意。
- 帶有光澤的漸變色。
- 彩色區(qū)域下方的一個(gè)小陰影。
- 標(biāo)題周?chē)?code>stroke line。
陰影區(qū)域是10點(diǎn)。 這就是label下的底部約束為10的原因。您知道完整標(biāo)題的高度為50。因此,彩色區(qū)域?yàn)?0。
Preparing the Header
為什么不通過(guò)賦予每種不同的顏色來(lái)直觀地定義這些區(qū)域? 您將為漸變區(qū)域指定紅色背景并使陰影區(qū)域變?yōu)榫G色。
在CustomHeader.swift中,在標(biāo)題label聲明后面添加以下行:
@IBInspectable var coloredBoxHeight: CGFloat = 40
@IBInspectable值允許您直接從Interface Builder執(zhí)行盡可能多的UI自定義。
將任何數(shù)字聲明為常量或?qū)傩远皇窃诖a中分散許多數(shù)字是一種很好的做法。 大多數(shù)情況下,幾天后查看自己的代碼時(shí),您會(huì)忘記使用的具體數(shù)字。
在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)
}
在UIView中draw(_:)是放置任何您想要用來(lái)更改自定義視圖外觀的自定義繪圖代碼的位置。 默認(rèn)繪制方法不執(zhí)行任何操作。 因此,請(qǐng)確保您重寫(xiě)。 這里有兩個(gè)步驟:
- 1) 計(jì)算要著色的兩個(gè)矩形。 第一個(gè)是具有漸變的區(qū)域。 第二個(gè)是陰影區(qū)域。 兩者都是基于您之前定義的
coloredBoxHeight計(jì)算的。 - 2) 獲取當(dāng)前的
Core Graphics上下文并繪制兩個(gè)彩色矩形。
現(xiàn)在,直接從Attributes inspector將CustomHeader.xib中標(biāo)題的label文本顏色更改為白色。
建立并運(yùn)行。 你應(yīng)該看到你的彩色標(biāo)題。

Drawing Drop Shadows
現(xiàn)在明確定義了矩形,添加陰影。 在CustomHeader.swift中,在coloredBoxHeight之后添加這兩個(gè)變量:
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)
接下來(lái),在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()
這就是你畫(huà)陰影的方式! 以下是上述代碼的含義,一步一步看一下:
- 1) 將陰影定義為灰色,透明度為50%。
- 2) 保存當(dāng)前圖形狀態(tài),以便您可以應(yīng)用所需的任何配置更改,并在完成后返回到此狀態(tài)。
- 3) 為要繪制的任何內(nèi)容設(shè)置陰影配置。
- 4) 畫(huà)出彩色的盒子。 如果沒(méi)有這個(gè),屏幕上就不會(huì)有陰影。
- 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)
}
這是為第二個(gè)table section顯示不同的顏色。 darkColor尚未使用,所以不要擔(dān)心。
建立并運(yùn)行。 您應(yīng)該看到上次運(yùn)行應(yīng)用程序時(shí)的巨大改進(jìn)。 標(biāo)題現(xiàn)在看起來(lái)更好,對(duì)吧? 接下來(lái),您將添加光澤效果。

Adding a Gloss Effect
應(yīng)用光澤效果的方法不止一種。 Matt Gallagher和Michael Heyeck解釋了更難的方法,但在這里,你將學(xué)習(xí)一種簡(jiǎn)單的方法。
為簡(jiǎn)單起見(jiàn),通過(guò)應(yīng)用漸變alpha蒙版來(lái)實(shí)現(xiàn)光澤效果的近似是現(xiàn)在足夠好的方法。
專(zhuān)業(yè)提示:這是一種常用的方法,為什么不把它放在一個(gè)單獨(dú)的文件中,以便在以后的項(xiàng)目中輕松訪問(wèn)?Extensions.swift是該作業(yè)的文件。 它有一些方便的擴(kuò)展,使事情變得更容易。
在CGContext擴(kuò)展的末尾,添加以下方法:
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) 從示例項(xiàng)目中調(diào)用擴(kuò)展文件中的另一個(gè)方法,該方法在矩形中繪制雙色漸變。
- 2) 定義兩種白色光澤顏色。
- 3) 計(jì)算將具有白色漸變或光澤的矩形。 此矩形是彩色漸變區(qū)域的一半。
- 4) 在較小的矩形中繪制白色漸變。
在CustomHeader.swift中,在draw(_:)結(jié)束時(shí),添加以下行:
context.drawGlossAndGradient(
rect: coloredBoxRect,
startColor: lightColor,
endColor: darkColor)
構(gòu)建并運(yùn)行。 你會(huì)看到一個(gè)漂亮的標(biāo)題,帶有漸變色和光澤效果。

你需要的最后一件事是在標(biāo)題的彩色區(qū)域周?chē)M(jìn)行stroke。 在剛添加的行之后,添加以下行:
context.setStrokeColor(darkColor.cgColor)
context.setLineWidth(1)
context.stroke(coloredBoxRect.rectFor1PxStroke())
建立并運(yùn)行。 注意你想要的較暗的stroke。

CGContext有很多有趣的繪圖工具,可用于繪制路徑,線條,形狀,文本和圖像。 值得查看developer documentation并進(jìn)行實(shí)驗(yàn)。
后記
本篇主要講述了Shadows 和 Gloss,感興趣的給個(gè)贊或者關(guān)注~~~
