版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2019.02.12 星期二 |
前言
quartz
是一個通用的術(shù)語,用于描述在iOS
和MAC OS X
中整個媒體層用到的多種技術(shù) 包括圖形顶伞、動畫廉油、音頻、適配撩笆。Quart 2D
是一組二維繪圖和渲染API
捺球,Core Graphic
會使用到這組API
,Quartz Core
專指Core Animation
用到的動畫相關(guān)的庫夕冲、API
和類氮兵。CoreGraphics
是UIKit
下的主要繪圖系統(tǒng),頻繁的用于繪制自定義視圖歹鱼。Core Graphics
是高度集成于UIView
和其他UIKit
部分的泣栈。Core Graphics
數(shù)據(jù)結(jié)構(gòu)和函數(shù)可以通過前綴CG
來識別。在app中很多時候繪圖等操作我們要利用CoreGraphic
框架,它能繪制字符串南片、圖形掺涛、漸變色等等,是一個很強大的工具疼进。感興趣的可以看我另外幾篇薪缆。
1. CoreGraphic框架解析(一)—— 基本概覽
2. CoreGraphic框架解析(二)—— 基本使用
3. CoreGraphic框架解析(三)—— 類波浪線的實現(xiàn)
4. CoreGraphic框架解析(四)—— 基本架構(gòu)補充
5. CoreGraphic框架解析 (五)—— 基于CoreGraphic的一個簡單繪制示例 (一)
6. CoreGraphic框架解析 (六)—— 基于CoreGraphic的一個簡單繪制示例 (二)
7. CoreGraphic框架解析 (七)—— 基于CoreGraphic的一個簡單繪制示例 (三)
8. CoreGraphic框架解析 (八)—— 基于CoreGraphic的一個簡單繪制示例 (四)
9. CoreGraphic框架解析 (九)—— 一個簡單小游戲 (一)
10. CoreGraphic框架解析 (十)—— 一個簡單小游戲 (二)
11. CoreGraphic框架解析 (十一)—— 一個簡單小游戲 (三)
12. CoreGraphic框架解析 (十二)—— Shadows 和 Gloss (一)
13. CoreGraphic框架解析 (十三)—— Shadows 和 Gloss (二)
14. CoreGraphic框架解析 (十四)—— Arcs 和 Paths (一)
15. CoreGraphic框架解析 (十五)—— Arcs 和 Paths (二)
開始
首先看下寫作環(huán)境
Swift 4.2, iOS 12, Xcode 10
在本教程中,您將學(xué)習(xí)如何使用Core Graphics
繪制線條伞广,矩形和漸變 - 從美化表格視圖開始拣帽!
這篇將揭開Core Graphics的神秘面紗。您將通過實際練習(xí)逐步學(xué)習(xí)API嚼锄,首先使用Core Graphics
美化table views
减拭。
Core Graphics
是iOS上非常酷的API灾票。作為開發(fā)人員峡谊,您可以使用它來自定義您的UI,并使用一些非常簡潔的效果刊苍,通常甚至無需讓設(shè)計師參與其中既们。任何與2D繪圖相關(guān)的東西 - 比如繪制形狀,填充它們并賦予它們漸變 - 都是使用Core Graphics的一個很好的選擇正什。
Core Graphics的歷史可以追溯到OS X
的早期階段啥纸,是目前仍在使用的最古老的API之一。也許這就是為什么婴氮,對于許多iOS開發(fā)人員來說斯棒,Core Graphics起初可能有些令人生畏:它是一個龐大的API,并且有很多障礙可以發(fā)現(xiàn)主经。但是荣暮,自從Swift 3以來,C風(fēng)格的API已經(jīng)更新罩驻,看起來和感覺就像您熟悉和喜愛的現(xiàn)代Swift API穗酥!
在本教程中,您將構(gòu)建一個Star Wars Top Trumps
應(yīng)用程序惠遏,該應(yīng)用程序由包含Starships
列表的主視圖組成:
以及一個每個Starship
的詳細視圖
在創(chuàng)建此應(yīng)用程序時砾跃,您將學(xué)習(xí)如何開始使用Core Graphics,如何填充和描邊矩形以及如何繪制線條和漸變以制作自定義表格視圖單元格和背景节吮。
是時候與Core Graphics
享受一些樂趣了抽高!
打開入門項目并快速瀏覽一下。該應(yīng)用程序基于Xcode提供的Master-Detail App
模板透绩。主視圖控制器包含Star Ships
列表翘骂,詳細視圖控制器顯示每艘船的詳細信息壁熄。
打開MasterViewController.swift
。在該類的頂部雏胃,注意一個starships
變量,它包含Starship
類型的數(shù)組和StarshipDataProvider
類型的dataProvider
變量瞭亮。
通過Command-單擊StarshipDataProvider
并選擇Jump to Definition
跳轉(zhuǎn)到StarshipDataProvider.swift
。這是一個簡單的類,它讀取bundle
文件Starships.json
,并將內(nèi)容轉(zhuǎn)換為Starship
數(shù)組。
你可以在Starship.swift
找到Starship
的定義衷畦。它只是一個簡單的結(jié)構(gòu)體栗涂,具有Starships
常見屬性的屬性。
接下來祈争,打開DetailViewController.swift
斤程。在類定義為枚舉之前定義在文件的頂部,FieldsToDisplay
菩混,它定義要在枚舉中顯示的Starship
屬性的人類可讀標題忿墅。在這個文件中,tableView(_:cellForRowAt :)
只是一個很大的switch
語句沮峡,用于將每個Starship
屬性的數(shù)據(jù)格式化為正確的格式疚脐。
構(gòu)建并運行應(yīng)用程序。
登陸頁面是MasterViewController
邢疙,顯示星球大戰(zhàn)宇宙中的星艦列表棍弄。 點擊以選擇X-wing
,應(yīng)用程序?qū)?dǎo)航到該船的詳細視圖秘症,其中顯示了X翼的圖像,然后是各種屬性式矫,例如它的成本和飛行速度乡摹。
這是一個功能齊全,如果非常無聊的應(yīng)用程序采转。 是時候添加一些bling
了聪廉!
Analyzing the Table View Style
在本教程中瞬痘,您將為兩個不同的表視圖添加不同的樣式。 仔細看看這些變化是什么樣的板熊。
在主視圖控制器中框全,每個單元格:
- 有從深藍色到黑色的漸變色。
- 以黃色勾勒出輪廓干签,從cell bounds 有一定的inset津辩。
并在詳細視圖控制器中:
- table本身有從深藍色到黑色的漸變色。
- 每個cell都有一個黃色分離線容劳,將其與相鄰cell分開喘沿。
要繪制這兩種設(shè)計,您只需要知道如何使用Core Graphics
繪制矩形竭贩,漸變和線條蚜印,這正是您將要學(xué)習(xí)的內(nèi)容。
Hello, Core Graphics!
雖然本教程涵蓋了在iOS上使用Core Graphics
留量,但重要的是要知道Core Graphics可用于所有主要的Apple平臺窄赋,包括通過AppKit
的MacOS
,iOS和通過UIKit
的tvOS
以及通過WatchKit
的Apple Watch
楼熄。
您可以考慮使用Core Graphics忆绰,如在物理畫布上繪畫;繪圖操作的順序很重要孝赫。例如较木,如果您繪制重疊的形狀,那么您添加的最后一個將位于頂部并與下面的重疊青柄。
Apple以這樣的方式構(gòu)建Core Graphics
伐债,使您作為開發(fā)人員在單獨的時刻提供有關(guān)繪制內(nèi)容的說明而不是在何處繪制。
由CGContext
類表示的核心圖形上下文定義了where
致开。您可以告訴上下文要執(zhí)行的繪制操作峰锁。 CGContexts
用于繪制到位圖圖像,繪制為PDF文件双戳,最常見的是直接繪制到UIView中虹蒋。
在這個繪畫類比中,核心圖形上下文代表畫家繪制的畫布飒货。
核心圖形上下文是狀態(tài)機(State Machines)
魄衅。也就是說,當您設(shè)置填充顏色時塘辅,可以為整個畫布設(shè)置填充顏色晃虫,并且在您更改之前,您繪制的任何形狀都將具有相同的填充顏色扣墩。
每個UIView
都有自己的核心圖形上下文哲银。要使用Core Graphics繪制UIView的內(nèi)容扛吞,必須在視圖的draw(_ :)
中編寫繪圖代碼。這是因為iOS在調(diào)用draw(_ :)
之前設(shè)置了正確的CGContext
以便繪制到視圖中荆责。
現(xiàn)在您了解了如何在UIKit中使用Core Graphics的基礎(chǔ)知識滥比,現(xiàn)在是時候更新您的應(yīng)用了!
Drawing Rectangles
首先做院,通過從“文件”菜單中選擇New ? File…
來創(chuàng)建新的視圖文件盲泛。選擇Cocoa Touch Class
,按Next
山憨,然后將類名設(shè)置為StarshipsListCellBackground
查乒。使其成為UIView的子類,然后創(chuàng)建類文件郁竟。將以下代碼添加到新類:
override func draw(_ rect: CGRect) {
// 1
guard let context = UIGraphicsGetCurrentContext() else {
return
}
// 2
context.setFillColor(UIColor.red.cgColor)
// 3
context.fill(bounds)
}
下面逐行分析:
- 1) 首先玛迄,使用
UIGraphicsGetCurrentContext()
獲取此UIView
實例的當前CGContext
。請記住棚亩,iOS會在調(diào)用draw(_ :)
之前自動為您設(shè)置蓖议。如果由于任何原因無法獲取上下文,則可以從方法中提前返回讥蟆。 - 2) 然后勒虾,在上下文本身上設(shè)置填充顏色。
- 3) 最后瘸彤,您告訴它填充視圖的邊界修然。
如您所見,Core Graphics API
不包含直接繪制填充顏色的形狀的方法质况。相反愕宋,有點像添加油漆到特定的畫筆,你將顏色設(shè)置為CGContext
的狀態(tài)结榄,然后中贝,你告訴上下文分別用該顏色繪制什么。
您可能還注意到臼朗,當您在上下文中調(diào)用setFillColor(_ :)
時邻寿,您沒有提供標準的UIColor
。相反视哑,您必須使用CGColor
绣否,這是Core Graphics
內(nèi)部用于表示顏色的基本數(shù)據(jù)類型。只需訪問任何UIColor的cgColor
屬性挡毅,將UIColor轉(zhuǎn)換為CGColor非常容易蒜撮。
1. Showing Your New Cell
要查看您的新視圖,請打開MasterViewController.swift
慷嗜。在tableView(_:cellForRowAt :)
中淀弹,在方法的第一行中出現(xiàn)單元格后立即添加以下代碼:
if !(cell.backgroundView is StarshipsListCellBackground) {
cell.backgroundView = StarshipsListCellBackground()
}
if !(cell.selectedBackgroundView is StarshipsListCellBackground) {
cell.selectedBackgroundView = StarshipsListCellBackground()
}
此代碼將單元格的背景視圖設(shè)置為新視圖的背景視圖。 構(gòu)建并運行應(yīng)用程序庆械,您將在每個單元格中看到可愛的薇溃,如果花哨的紅色背景。
驚人缭乘! 您現(xiàn)在可以使用Core Graphics
進行繪制沐序。 不管你信不信,你已經(jīng)學(xué)會了一系列非常重要的技巧:如何繪制上下文堕绩,如何更改填充顏色以及如何用顏色填充矩形策幼。 你可以用它制作一些非常漂亮的用戶界面。
但是你要更進一步奴紧,學(xué)習(xí)一種最有用的技術(shù)來制作優(yōu)秀的用戶界面:漸變特姐!
Creating New Colors
您將在此項目中反復(fù)使用相同的顏色,因此為UIColor
創(chuàng)建一個擴展黍氮,以使這些顏色易于訪問唐含。 轉(zhuǎn)到File ? New ? File…
并創(chuàng)建一個名為UIColorExtensions.swift
的新Swift文件。 用以下內(nèi)容替換文件的內(nèi)容:
import UIKit
extension UIColor {
public static let starwarsYellow =
UIColor(red: 250/255, green: 202/255, blue: 56/255, alpha: 1.0)
public static let starwarsSpaceBlue =
UIColor(red: 5/255, green: 10/255, blue: 85/255, alpha: 1.0)
public static let starwarsStarshipGrey =
UIColor(red: 159/255, green: 150/255, blue: 135/255, alpha: 1.0)
}
此代碼定義了三種新顏色沫浆,您可以在UIColor
上以靜態(tài)屬性的形式訪問這些顏色捷枯。
Drawing Gradients
接下來,由于您要在此項目中繪制大量漸變专执,因此請?zhí)砑虞o助方法來繪制漸變淮捆。 這將通過將漸變代碼保存在一個位置來簡化項目,并避免重復(fù)自己本股。
選擇File ? New ? File…
并創(chuàng)建一個名為CGContextExtensions.swift
的新Swift文件攀痊。 用以下內(nèi)容替換文件的內(nèi)容:
import UIKit
extension CGContext {
func drawLinearGradient(
in rect: CGRect,
startingWith startColor: CGColor,
finishingWith endColor: CGColor
) {
// 1
let colorSpace = CGColorSpaceCreateDeviceRGB()
// 2
let locations = [0.0, 1.0] as [CGFloat]
// 3
let colors = [startColor, endColor] as CFArray
// 4
guard let gradient = CGGradient(
colorsSpace: colorSpace,
colors: colors,
locations: locations
) else {
return
}
}
}
這個方法做了很多:
- 1) 首先,設(shè)置正確的色彩空間痊末。您可以使用色彩空間做很多事情蚕苇,但是您幾乎總是希望使用
CGColorSpaceCreateDeviceRGB
來使用與設(shè)備相關(guān)的標準RGB色彩空間。 - 2) 接下來凿叠,設(shè)置一個數(shù)組涩笤,跟蹤漸變范圍內(nèi)每種顏色的位置。值0表示漸變的開始盒件,1表示漸變的結(jié)束蹬碧。
注意:如果需要,可以在漸變中使用三種或更多顏色炒刁,并且可以設(shè)置每種顏色在漸變中的位置恩沽,就像這樣的數(shù)組。這對某些效果很有用翔始。
- 3) 之后罗心,使用傳遞給方法的顏色創(chuàng)建一個數(shù)組里伯。注意在這里使用
CFArray
而不是Array
,因為您正在使用較低級別的C API
渤闷。 - 4) 然后疾瓮,通過初始化
CGGradient
對象,傳入顏色空間飒箭,顏色數(shù)組和先前創(chuàng)建的位置來創(chuàng)建漸變狼电。如果由于某種原因,可選的初始化程序失敗弦蹂,則提前返回肩碟。
你現(xiàn)在有一個漸變引用,但它實際上還沒有繪制任何東西 - 它只是一個指向你稍后實際繪制時使用的信息的指針⊥勾唬現(xiàn)在幾乎是繪制漸變的時候了削祈,但在你做之前,還需要更多的理論脑漫。
1. The Graphics State Stack
請記住岩瘦,Core Graphics
上下文是狀態(tài)機。 在上下文中設(shè)置狀態(tài)時必須要小心窿撬,特別是在傳遞上下文的函數(shù)中启昧,或者在本例中是上下文本身的方法,因為在修改上下文之前無法知道上下文的狀態(tài)劈伴。 請考慮UIView中的以下代碼:
override func draw(_ rect: CGRect) {
// ... get context
context.setFillColor(UIColor.red.cgColor)
drawBlueCircle(in: context)
context.fill(someRect)
}
// ... many lines later
func drawBlueCircle(in context: CGContext) {
context.setFillColor(UIColor.blue.cgColor)
context.addEllipse(in: bounds)
context.drawPath(using: .fill)
}
看一下這段代碼密末,您可能會認為它會在視圖中繪制一個紅色矩形和一個藍色圓圈,但你錯了跛璧! 相反严里,這段代碼繪制了一個藍色矩形和一個藍色圓圈 - 但為什么呢?
因為drawBlueCircle(in :)
在上下文中設(shè)置了藍色填充顏色追城,并且因為上下文是狀態(tài)機刹碾,所以它會覆蓋先前的紅色填充顏色集。
這就是saveGState()
及其伙伴方法restoreGState()
的用武之地座柱!
每個CGContext
都維護一個圖形狀態(tài)的堆棧迷帜,其中包含當前繪圖環(huán)境的大部分(盡管不是全部)方面。 saveGState()
將當前狀態(tài)的副本推送到圖形狀態(tài)堆棧色洞,然后您可以使用restoreGState()
將上下文恢復(fù)到該狀態(tài)戏锹,并在該過程中從堆棧中刪除狀態(tài)。
在上面的示例中火诸,您應(yīng)該像這樣修改drawBlueLines(in :)
:
func drawBlueCircle(in context: CGContext) {
context.saveGState()
context.setFillColor(UIColor.blue.cgColor)
context.addEllipse(in: bounds)
context.drawPath(using: .fill)
context.restoreGState()
}
您可以打開RedBluePlayground.playground
來自行測試锦针。
2. Completing the Gradient
掌握有關(guān)圖形狀態(tài)堆棧的知識,是時候完成繪制背景漸變了。 將以下內(nèi)容添加到drawLinearGradient(in:startingWith:finishingWith:)
的末尾:
// 5
let startPoint = CGPoint(x: rect.midX, y: rect.minY)
let endPoint = CGPoint(x: rect.midX, y: rect.maxY)
// 6
saveGState()
// 7
addRect(rect)
clip()
drawLinearGradient(
gradient,
start: startPoint,
end: endPoint,
options: CGGradientDrawingOptions()
)
restoreGState()
- 5) 首先計算漸變的起點和終點奈搜。您可以將其設(shè)置為從矩形的頂部中間到底部中間的線悉盆。有用的是,
CGRect
包含一些實例變量馋吗,如midX
和maxY
舀瓢,這使得這非常簡單。 - 6) 接下來耗美,由于您即將修改上下文的狀態(tài),因此您可以保存其圖形狀態(tài)并通過還原它來結(jié)束該方法航缀。
- 7) 最后商架,在提供的矩形中繪制漸變。
drawLinearGradient(_:start:end:options :)
是實際繪制漸變的方法芥玉,但除非另有說明蛇摸,否則它將使用漸變填充整個上下文,即整個視圖灿巧。在這里赶袄,您只想填充提供的矩形中的漸變。要做到這一點抠藕,你需要了解clipping
饿肺。
剪切(clipping)
是Core Graphics
中一個非常棒的功能,可以將繪圖限制為任意形狀盾似。您所要做的就是將形狀添加到上下文中敬辣,然后,不要像通常那樣填充它零院,而是在上下文中調(diào)用clip()
溉跃,然后將所有未來的繪制限制到該區(qū)域。
因此告抄,在這種情況下撰茎,您將在最終調(diào)用drawLinearGradient(_:start:end:options :)
繪制漸變之前,在上下文和剪輯上設(shè)置提供的矩形打洼。
是時候給這個方法一個旋轉(zhuǎn)龄糊!打開StarshipsListCellBackground.swift
,在獲取當前的UIGraphicsContext
之后募疮,用以下內(nèi)容替換代碼:
let backgroundRect = bounds
context.drawLinearGradient(
in: backgroundRect,
startingWith: UIColor.starwarsSpaceBlue.cgColor,
finishingWith: UIColor.black.cgColor
)
構(gòu)建并運行
您現(xiàn)在已成功將漸變背景添加到自定義單元格绎签。 干得好,但是酝锅,可以公平地說诡必,現(xiàn)在成品并不是很好看。 是時候用一些標準的UIKit主題來修復(fù)它了。
Fixing the Theme
打開Main.storyboard
并選擇Master scene
中的表格視圖爸舒。 在“屬性”檢查器中蟋字,將Separator
設(shè)置為None
。
然后扭勉,在Master Navigation Controller
場景中選擇Navigation Bar
并將導(dǎo)航欄樣式設(shè)置為黑色并取消選擇半透明(Translucent)
鹊奖。 在Detail Navigation Controller
場景中重復(fù)Navigation Bar
。
接下來涂炎,打開MasterViewController.swift
忠聚。 在viewDidLoad()
的末尾,添加以下內(nèi)容:
tableView.backgroundColor = .starwarsSpaceBlue
然后在tableView(_:cellForRowAt :)
中唱捣,在返回單元格之前两蟀,設(shè)置文本的顏色:
cell.textLabel!.textColor = .starwarsStarshipGrey
最后,打開AppDelegate.swift
并在application(_:didFinishLaunchingWithOptions:)
中返回之前添加以下內(nèi)容:
// Theming
UINavigationBar.appearance().tintColor = .starwarsYellow
UINavigationBar.appearance().barTintColor = .starwarsSpaceBlue
UINavigationBar.appearance().titleTextAttributes =
[.foregroundColor: UIColor.starwarsStarshipGrey]
構(gòu)建并運行
那更好震缭!您的主表視圖開始看起來非常太空赂毯。
Stroking Paths
在Core Graphics
中進行描邊意味著沿著路徑繪制一條線,而不是像之前那樣填充它拣宰。
當Core Graphics
描繪路徑時党涕,它會在路徑的精確邊緣的中間繪制描邊線。這可能會導(dǎo)致一些常見問題巡社。
1. Outside the Bounds
首先膛堤,如果您正在繪制一個矩形的邊緣,例如晌该,邊框骑祟,默認情況下,Core Graphics將不會繪制一半的描邊路徑气笙。
為什么次企?因為為UIView
設(shè)置的上下文僅擴展到視圖的邊界。想象一下潜圃,在視圖邊緣周圍有一個點邊框缸棵。因為Core Graphics在路徑的中間向下劃線,所以該線將在視圖邊界之外半個點谭期,在視圖邊界內(nèi)半個點堵第。
一個常見的解決方案是將行程的路徑插入每個方向的線寬度的一半,使其位于視圖內(nèi)隧出。
下圖顯示了一個黃色矩形踏志,在灰色背景上有一個點寬的紅色描邊,以一個點間隔條紋胀瞪。在左圖中针余,描邊路徑遵循視圖的邊界并已被裁剪饲鄙。您可以看到這一點,因為紅線是灰色方塊寬度的一半圆雁。在右圖中忍级,描邊路徑已插入半個點的間隔,現(xiàn)在具有正確的線寬伪朽。
2. Anti-Aliasing
其次轴咱,您需要了解可能影響邊框外觀的抗鋸齒效果。消除鋸齒烈涮,如果您不熟悉它(即使您可能在計算機游戲設(shè)置屏幕上聽說過它F臃巍),也是一種渲染引擎用于避免在顯示圖形時出現(xiàn)“鋸齒狀”邊緣和線條的技術(shù)不要完美映射到設(shè)備上的物理像素坚洽。
以前一段視圖周圍的一點邊框為例戈稿。如果邊框遵循視圖的邊界,則Core Graphics將嘗試在矩形的任一側(cè)繪制半個點寬的線酪术。
在非視網(wǎng)膜顯示器上,一個點等于設(shè)備上的一個像素翠储。不可能只照亮一半像素绘雁,因此Core Graphics將使用消除鋸齒來繪制兩個像素,但是在較淺的陰影中只能呈現(xiàn)單個像素的外觀援所。
在以下幾組屏幕截圖中庐舟,左圖像是非視網(wǎng)膜顯示器,中間圖像是視網(wǎng)膜顯示器住拭,其比例為2挪略,第三圖像是視網(wǎng)膜顯示器,其比例為3滔岳。
對于第一個圖杠娱,請注意2x圖像如何不顯示任何抗鋸齒,因為黃色矩形的兩邊的半點落在像素邊界上谱煤。然而摊求,在1x和3x圖像中發(fā)生抗鋸齒。
在下一組屏幕截圖中刘离,描邊矩形已插入半個點間隔室叉,使得筆劃線與點精確對齊,從而與像素邊界對齊硫惕。 注意沒有鋸齒偽像茧痕。
Adding a Border
回到你的應(yīng)用程序! cell開始看起來很好恼除,但你會增加另一種觸感踪旷,讓它們脫穎而出。 這一次,你將在cell邊緣繪制一個明亮的黃色框埃脏。
您已經(jīng)知道如何輕松填充矩形搪锣。 好吧,在他們周圍描邊也同樣容易彩掐。
打開StarshipsListCellBackground.swift
并將以下內(nèi)容添加到draw(_ :)
的底部:
let strokeRect = backgroundRect.insetBy(dx: 4.5, dy: 4.5)
context.setStrokeColor(UIColor.starwarsYellow.cgColor)
context.setLineWidth(1)
context.stroke(strokeRect)
在這里构舟,您可以創(chuàng)建一個用于描邊的矩形,它在x和y方向上從背景矩形中插入4.5個點堵幽。 然后將描邊顏色設(shè)置為黃色狗超,將線寬設(shè)置為一個點,最后描邊矩形朴下。 構(gòu)建并運行您的項目努咐。
現(xiàn)在你的星艦列表真的看起來像是來自遙遠的星系!
Building a Card Layout
雖然你的主視圖控制器看起來很花哨殴胧,但細節(jié)視圖控制器仍然需要一些修飾渗稍!
對于此視圖,您將首先使用自定義UITableView
子類在表視圖背景上繪制漸變团滥。
創(chuàng)建一個名為StarshipTableView.swift
的新Swift文件竿屹。 用以下內(nèi)容替換生成的代碼:
import UIKit
class StarshipTableView: UITableView {
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else {
return
}
let backgroundRect = bounds
context.drawLinearGradient(
in: backgroundRect,
startingWith: UIColor.starwarsSpaceBlue.cgColor,
finishingWith: UIColor.black.cgColor
)
}
}
現(xiàn)在這應(yīng)該開始變得熟悉了。 在新表視圖子類的draw(_ :)
方法中灸姊,您將獲得當前的CGContext
拱燃,然后在視圖的邊界繪制一個漸變,從頂部的藍色開始力惯,在底部朝向黑色碗誉。 簡單!
打開Main.storyboard
并單擊Detail
場景中的TableView
父晶。 在Identity
檢查器中哮缺,將類設(shè)置為新的StarshipTableView
。
構(gòu)建并運行應(yīng)用程序甲喝,然后點擊X-wing
那一行 蝴蜓。
您的詳細視圖現(xiàn)在具有從上到下運行的漂亮的全屏漸變,但表格視圖中的單元格遮擋了效果的最佳部分俺猿。 是時候解決這個問題并為細節(jié)cell添加更多的天賦茎匠。
回到Main.storyboard
,在Detail Scene
中選擇FieldCell
押袍。 在“屬性”檢查器中诵冒,將背景設(shè)置為Clear Color
。 接下來谊惭,打開DetailViewController.swift
汽馋,在tableView(_:cellForRowAt :)
的最底部首装,在返回單元格之前蕾总,添加以下內(nèi)容:
cell.textLabel!.textColor = .starwarsStarshipGrey
cell.detailTextLabel!.textColor = .starwarsYellow
這只是將單元格的字段名稱和值設(shè)置為適合星球大戰(zhàn)主題的更合適的顏色收苏。
然后台诗,在tableView(_:cellForRowAt :)
之后添加以下方法來設(shè)置表視圖頭的樣式:
override func tableView(
_ tableView: UITableView,
willDisplayHeaderView view: UIView,
forSection section: Int
) {
view.tintColor = .starwarsYellow
if let header = view as? UITableViewHeaderFooterView {
header.textLabel?.textColor = .starwarsSpaceBlue
}
}
在這里,您將表格視圖的標題視圖的色調(diào)顏色設(shè)置為主題黃色铁蹈,為其提供黃色背景宽闲,并將其文本顏色設(shè)置為主題藍色。
Drawing Lines
作為bling
的最后一點握牧,您將在詳細視圖中為每個單元格添加一個拆分器容诬。 創(chuàng)建一個新的Swift文件,這次稱為YellowSplitterTableViewCell.swift
沿腰。 用以下內(nèi)容替換生成的代碼:
import UIKit
class YellowSplitterTableViewCell: UITableViewCell {
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else {
return
}
let y = bounds.maxY - 0.5
let minX = bounds.minX
let maxX = bounds.maxX
context.setStrokeColor(UIColor.starwarsYellow.cgColor)
context.setLineWidth(1.0)
context.move(to: CGPoint(x: minX, y: y))
context.addLine(to: CGPoint(x: maxX, y: y))
context.strokePath()
}
}
在YellowSplitterTableVIewCell
中览徒,您使用Core Graphics
來劃分單元格邊界底部的一條線。 注意所使用的y值是如何比視圖的邊界小半個點颂龙,以確保分割器完全在單元內(nèi)繪制习蓬。
現(xiàn)在,您需要實際繪制顯示拆分器的線措嵌。
要在A和B之間繪制一條線躲叼,首先移動到A點,這不會導(dǎo)致Core Graphics繪制任何東西铅匹。 然后押赊,您將一條線添加到B點饺藤,該線將點A到點B的線添加到上下文中包斑。 然后,您可以調(diào)用strokePath()
來描邊該行涕俗。
最后罗丰,再次打開Main.storyboard
并使用Identity檢查器將Detail
場景中的FieldCell
類設(shè)置為新創(chuàng)建的YellowSplitterTableViewCell
。 構(gòu)建并運行您的應(yīng)用程序再姑。 然后萌抵,打開X-wing
細節(jié)視圖。 漂亮元镀!
后記
本篇主要講述了Lines, Rectangles 和 Gradients绍填,感興趣的給個贊或者關(guān)注~~~