第一部分
創(chuàng)建顏色主題
為了在應(yīng)用程序中創(chuàng)建一致的外觀考榨,您將創(chuàng)建一個主題,其中包含兩個對比的顏色屬性鹦倚。您將使用主顏色作為視圖的背景顏色河质,使用強調(diào)顏色作為視圖的文本顏色。
注意:
請確保您使用的是本頁面頂部鏈接處提供的起始項目申鱼。下面的步驟使用該項目中定義的顏色愤诱。
步驟1
在項目導航器中,創(chuàng)建一個名為Models的新組捐友。
步驟2
在Models組中,創(chuàng)建一個名為Theme.swift的新的Swift文件溃槐。
步驟3
導入SwiftUI框架而不是Foundation框架匣砖。
盡管在本節(jié)中您并沒有創(chuàng)建一個視圖,但您可以從SwiftUI框架中添加顏色屬性昏滴。SwiftUI將顏色視為可以直接添加到視圖層次結(jié)構(gòu)中的視圖實例猴鲫。
步驟4
創(chuàng)建一個名為Theme的枚舉,其原始值類型為String谣殊。
Swift會自動創(chuàng)建與每個添加到Theme中的case名稱匹配的字符串拂共。
注意事項
編譯器會生成錯誤,因為枚舉必須有case來聲明原始類型姻几。您將在下一步中修復(fù)此錯誤宜狐。
起始項目包括資源目錄势告,并為每個顏色定義了RGBA值。
步驟5
為資產(chǎn)目錄中的Themes文件夾中列出的每種顏色添加case抚恒。
資源目錄中的命名顏色必須與代碼中的引用匹配咱台,因此請確保正確拼寫每個case的名稱。
步驟6
添加一個名為accentColor的Color屬性俭驮,根據(jù)self的值返回.black或.white回溺。
強調(diào)顏色為主題的主色提供了高對比度的補充,確保您的視圖保持可訪問性混萝。
步驟7
添加一個名為mainColor的Color屬性遗遵,使用枚舉的rawValue創(chuàng)建一個顏色。
此屬性從資源目錄中初始化一個顏色逸嘀。
Theme.swift
import SwiftUI
enum Theme: String {
case bubblegum
case buttercup
case indigo
case lavender
case magenta
case navy
case orange
case oxblood
case periwinkle
case poppy
case purple
case seafoam
case sky
case tan
case teal
case yellow
var accentColor: Color {
switch self {
case .bubblegum, .buttercup, .lavender, .orange, .periwinkle, .poppy, .seafoam, .sky, .tan, .teal, .yellow: return .black
case .indigo, .magenta, .navy, .oxblood, .purple: return .white
}
}
var mainColor: Color {
Color(rawValue)
}
}
Section 2
創(chuàng)建每日站會模型
DailyScrum模型將包含以下四個屬性车要,均為簡單值類型:title、attendees厘熟、lengthInMinutes和theme屯蹦。因為DailyScrum主要用于攜帶值數(shù)據(jù),所以您將它聲明為結(jié)構(gòu)體绳姨,使其成為值類型登澜。
Step 1
在Models組中添加一個名為DailyScrum的新Swift文件。
Step 2
創(chuàng)建一個DailyScrum結(jié)構(gòu)體飘庄,包含title脑蠕、attendees、lengthInMinutes和theme屬性跪削。
Step 3
添加一個擴展谴仙,提供一些示例數(shù)據(jù)。
DailyScrum.swift
import Foundation
struct DailyScrum {
var title: String
var attendees: [String]
var lengthInMinutes: Int
var theme: Theme
}
extension DailyScrum {
static let sampleData: [DailyScrum] =
[
DailyScrum(title: "Design",
attendees: ["Cathy", "Daisy", "Simon", "Jonathan"],
lengthInMinutes: 10,
theme: .yellow),
DailyScrum(title: "App Dev",
attendees: ["Katie", "Gray", "Euna", "Luis", "Darla"],
lengthInMinutes: 5,
theme: .orange),
DailyScrum(title: "Web Dev",
attendees: ["Chella", "Chris", "Christina", "Eden", "Karla", "Lindsey", "Aga", "Chad", "Jenn", "Sarah"],
lengthInMinutes: 5,
theme: .poppy)
]
}
Section 3
創(chuàng)建卡片視圖
CardView將總結(jié)DailyScrum模型的數(shù)據(jù)碾盐,并顯示標題晃跺、參與人數(shù)和持續(xù)時間。您將從較小的視圖中組合CardView毫玖,每個視圖顯示DailyScrum結(jié)構(gòu)中的一部分數(shù)據(jù)掀虎。
您將更新CardView_Previews結(jié)構(gòu),以便在開發(fā)視圖時獲得即時的可視反饋付枫。
Step 1
添加一個名為CardView的新的SwiftUI視圖文件烹玉。
如果預(yù)覽被暫停了,您可以恢復(fù)它阐滩,以觀察您在代碼中進行的更改在預(yù)覽中的反映二打。
Step 2
添加一個類型為DailyScrum的常量scrum。
注意
編譯器會生成一個錯誤掂榔,因為CardView()初始化程序現(xiàn)在需要一個DailyScrum參數(shù)继效。您將在下一步中解決此問題症杏。
Step 3
在CardView_Previews中,創(chuàng)建一個名為scrum的靜態(tài)變量莲趣,并將其傳遞給CardView的初始化程序鸳慈。
Step 4
使用scrum.theme.mainColor為預(yù)覽指定一個背景顏色。
Step 5
使用previewLayout修飾符將預(yù)覽的寬度設(shè)置為400喧伞,高度設(shè)置為60走芋。
設(shè)置預(yù)覽布局和背景顏色將CardView呈現(xiàn)為它將在List視圖中顯示的樣子。在下一個教程中潘鲫,您將將該視圖嵌入到列表中翁逞。
Step 6
將畫布設(shè)置從Live更改為Selectable。
Step 7
更新Text視圖以顯示scrum的標題溉仑,并將字體樣式設(shè)置為headline挖函。
Step 8
將Text視圖嵌入到具有l(wèi)eading對齊的VStack中。
VStack在垂直線上排列子視圖浊竟,并使用對齊參數(shù)將視圖沿水平軸的位置怨喘。
Step 9
在Spacer后面添加一個HStack,其中嵌套了一個Label用于顯示與會人數(shù)振定。
注意
Label和Image對于SF Symbol使用稍微不同的參數(shù)標簽必怜。在使用堆棧排列視圖中創(chuàng)建的Image使用的是Image(systemName:),而不是Label(:systemImage:)后频。
Step 10
在HStack中添加另一個Label梳庆,并將其系統(tǒng)圖像設(shè)置為“clock”。
Step 11
修改標簽以顯示會議持續(xù)時間卑惜。
您可以使用屬性檢查器自定義視圖膏执,代碼會相應(yīng)更新÷毒茫或者您可以直接在代碼中更改屬性更米。在兩種情況下,預(yù)覽都會更新以反映您的更改毫痕。
Step 12
在標簽之間添加一個Spacer壳快,以顯示圍繞視圖的信息。
CardView.swift
import SwiftUI
struct CardView: View {
let scrum: DailyScrum
var body: some View {
VStack(alignment: .leading) {
Text(scrum.title)
.font(.headline)
Spacer()
HStack {
Label("\(scrum.attendees.count)", systemImage: "person.3")
Label("\(scrum.lengthInMinutes)", systemImage: "clock")
}
}
}
}
struct CardView_Previews: PreviewProvider {
static var scrum = DailyScrum.sampleData[0]
static var previews: some View {
CardView(scrum: scrum)
.background(scrum.theme.mainColor)
.previewLayout(.fixed(width: 400, height: 60))
}
}
第四節(jié):美化卡片
卡片視圖顯示有關(guān)每日Scrum的信息镇草。在這一部分中,您將為卡片視圖添加樣式瘤旨,突出顯示最重要的信息梯啤,并修改視覺組件,以確保在明亮和暗黑模式下文本和背景視圖之間有足夠的對比度存哲。
Step 1
給會議時長標簽添加20個點的尾部填充因宇。
提示
您還可以在視圖的.leading七婴、.top和.bottom邊緣添加填充。
Step 2
將HStack中的所有字體樣式設(shè)置為標題察滑。
在標簽和圖像中使用的SF Symbols會隨著字體權(quán)重和大小的變化進行合理的縮放和對齊打厘。
Step 3
給VStack添加填充,使所有內(nèi)容從邊緣處靠近贺辰。
Step 4
將Xcode預(yù)覽模式從"Selectable"更改為"Color Scheme Variants"户盯,以在明亮和暗黑外觀中呈現(xiàn)視圖。
在暗黑模式中饲化,默認的淺色文本與黃色背景之間的對比度不足莽鸭。
Step 5
使用scrum.theme.accentColor設(shè)置foregroundColor。
在Theme.swift中定義的accentColor變量會根據(jù)明亮或暗黑主題返回黑色或白色吃靠。
CardView.swift
import SwiftUI
struct CardView: View {
let scrum: DailyScrum
var body: some View {
VStack(alignment: .leading) {
Text(scrum.title)
.font(.headline)
Spacer()
HStack {
Label("\(scrum.attendees.count)", systemImage: "person.3")
Spacer()
Label("\(scrum.lengthInMinutes)", systemImage: "clock")
.padding(.trailing, 20)
}
.font(.caption)
}
.padding()
.foregroundColor(scrum.theme.accentColor)
}
}
struct CardView_Previews: PreviewProvider {
static var scrum = DailyScrum.sampleData[0]
static var previews: some View {
CardView(scrum: scrum)
.background(scrum.theme.mainColor)
.previewLayout(.fixed(width: 400, height: 60))
}
}
Section 5
自定義標簽樣式
接下來硫眨,您將創(chuàng)建一個標簽樣式,將會議時長和時鐘圖標水平堆疊在一起巢块。通過使用LabelStyle協(xié)議礁阁,您可以通過在多個視圖中重用相同的標簽樣式來創(chuàng)建一致的設(shè)計。
Step 1
創(chuàng)建一個名為TrailingIconLabelStyle.swift的新的Swift文件族奢。
Step 2
導入SwiftUI姥闭。
Step 3
創(chuàng)建一個名為TrailingIconLabelStyle的新結(jié)構(gòu)體,并符合LabelStyle協(xié)議歹鱼。
提示
如果您不想創(chuàng)建自定義的標簽樣式泣栈,您可以使用內(nèi)置的標簽樣式之一,它們使用系統(tǒng)標準布局顯示圖標弥姻、標題或兩者南片。
注意
編譯器會生成錯誤,因為該結(jié)構(gòu)體不符合LabelStyle協(xié)議的要求庭敦。
Step 4
創(chuàng)建一個空的makeBody(configuration:)函數(shù)疼进。
系統(tǒng)會在使用此樣式作為當前標簽樣式的視圖層次結(jié)構(gòu)中的每個Label實例中調(diào)用此方法。
注意
現(xiàn)在您的項目可以編譯通過秧廉,沒有錯誤了伞广。
Step 5
添加一個HStack。
Step 6
在HStack內(nèi)部添加configuration.title和configuration.icon疼电。
configuration參數(shù)是一個LabelStyleConfiguration嚼锄,其中包含圖標和標題視圖。這些視圖表示標簽的圖像和標簽文本蔽豺。
Step 7
在LabelStyle上添加一個擴展区丑,創(chuàng)建一個名為trailingIcon的靜態(tài)屬性。
因為您將標簽樣式定義為靜態(tài)屬性,所以可以使用前導點語法來調(diào)用它沧侥,這樣可以使您的代碼更易讀可霎。
Step 8
在CardView.swift文件中的lengthInMinutes標簽上,用新的標簽樣式替換padding宴杀。
現(xiàn)在癣朗,時鐘圖標對齊到尾部,與參與人數(shù)標簽對齊。
在視覺上,CardView已經(jīng)完成游岳,您可以在列表中顯示它毡们。在這之前,您將使用無障礙修飾符來改善VoiceOver用戶的體驗。
TrailingIconLabelStyle.swift
import SwiftUI
struct TrailingIconLabelStyle: LabelStyle {
func makeBody(configuration: Configuration) -> some View {
HStack {
configuration.title
configuration.icon
}
}
}
CardView.swift
import SwiftUI
struct CardView: View {
let scrum: DailyScrum
var body: some View {
VStack(alignment: .leading) {
Text(scrum.title)
.font(.headline)
Spacer()
HStack {
Label("\(scrum.attendees.count)", systemImage: "person.3")
Spacer()
Label("\(scrum.lengthInMinutes)", systemImage: "clock")
.labelStyle(.trailingIcon)
}
.font(.caption)
}
.padding()
.foregroundColor(scrum.theme.accentColor)
}
}
struct CardView_Previews: PreviewProvider {
static var scrum = DailyScrum.sampleData[0]
static var previews: some View {
CardView(scrum: scrum)
.background(scrum.theme.mainColor)
.previewLayout(.fixed(width: 400, height: 60))
}
}
Section 6
使卡片視圖具有可訪問性
現(xiàn)在CardView在視覺上已經(jīng)布局完成,您將使其對所有用戶具有可訪問性。您將為您的視圖添加無障礙修飾符穗酥,以使VoiceOver更容易理解和導航您的界面。
CardView包含一個帶有時鐘圖像和表示會議時長的數(shù)字的標簽惠遏。它還包含一個人物圖像和與會人數(shù)砾跃。
您將添加使用字符串插值的無障礙標簽,以使標簽成為視圖的有意義描述节吮。VoiceOver將讀取“4名與會人員”和“10分鐘會議”抽高。
Step 1
在顯示scrum標題的文本視圖上應(yīng)用accessibilityAddTraits(.isHeader)修飾符。
此修飾符通過讀取scrum標題后跟“標題”來幫助傳達視圖的信息架構(gòu)透绩。
Step 2
使用accessibility修飾符為HStack中的第一個Label添加描述其內(nèi)容的標簽翘骂。
Step 3
為HStack中的第二個Label添加類似的accessibility修飾符。
CardView.swift
import SwiftUI
struct CardView: View {
let scrum: DailyScrum
var body: some View {
VStack(alignment: .leading) {
Text(scrum.title)
.font(.headline)
.accessibilityAddTraits(.isHeader)
Spacer()
HStack {
Label("\(scrum.attendees.count)", systemImage: "person.3")
.accessibilityLabel("\(scrum.attendees.count) attendees")
Spacer()
Label("\(scrum.lengthInMinutes)", systemImage: "clock")
.accessibilityLabel("\(scrum.lengthInMinutes) minute meeting")
.labelStyle(.trailingIcon)
}
.font(.caption)
}
.padding()
.foregroundColor(scrum.theme.accentColor)
}
}
struct CardView_Previews: PreviewProvider {
static var scrum = DailyScrum.sampleData[0]
static var previews: some View {
CardView(scrum: scrum)
.background(scrum.theme.mainColor)
.previewLayout(.fixed(width: 400, height: 60))
}
}
下一個教程將向您展示如何在SwiftUI List中使用CardView帚豪。您將了解到SwiftUI如何通過將較小的視圖組合在一起來輕松構(gòu)建一個大而復(fù)雜的視圖碳竟,就像您剛剛創(chuàng)建的視圖一樣。