聊聊如何自定義 SwiftUI 中符號圖像的外觀
前言
符號圖像是來自 Apple的SF Symbols 庫的矢量圖標,設(shè)計用于在 Apple 平臺上使用。這些可縮放的圖像適應(yīng)不同的大小和重量,確保在我們的應(yīng)用程序中具有一致的高質(zhì)量圖標。在 SwiftUI 中使用符號圖像非常簡單,只需使用 Image 視圖和所需符號的系統(tǒng)名稱。下面是一個快速示例:
import SwiftUI
struct ContentView: View {
var body: some View {
Image(systemName: "star")
}
}
圖片
大小
盡管符號被放置在Image視圖中,但它應(yīng)被視為文本。要調(diào)整符號的大小,我們可以應(yīng)用 font() 修飾符,就像在Text視圖中一樣。這使我們能夠?qū)⒎柕拇笮∨c不同的文本樣式對齊,確保UI的視覺一致性。
HStack {
Image(systemName: "star")
.font(.title)
Image(systemName: "star")
.font(.body)
Image(systemName: "star")
.font(.caption)
}
圖片
我們可以使用 fontWeight() 修飾符來調(diào)整符號的重量。這個修飾符改變符號筆畫的粗細,使我們能夠?qū)⒎柵c周圍的文本匹配或?qū)Ρ取?/p>
HStack {
Image(systemName: "star")
.fontWeight(.light)
Image(systemName: "star")
.fontWeight(.bold)
Image(systemName: "star")
.fontWeight(.black)
}
圖片
要根據(jù)字體大小相對縮放圖像,我們應(yīng)該使用 imageScale() 修飾符。有三個選項:小、中、大,它們根據(jù)字體大小按比例縮放符號。如果沒有明確設(shè)置字體,符號將從當前環(huán)境中繼承字體。
HStack {
Image(systemName: "star")
.imageScale(.small)
Image(systemName: "star")
.imageScale(.medium)
Image(systemName: "star")
.imageScale(.large)
}
.font(.headline)
圖片
不建議通過應(yīng)用resizable()修飾符并設(shè)置框架來調(diào)整符號圖像的大小,因為這樣做會使圖像停止作為符號圖像,從而影響其與文本的布局和對齊。
顏色
使用SwiftUI中的foregroundStyle()視圖修飾符,可以輕松自定義符號圖像的顏色。這個修飾符允許我們直接設(shè)置符號圖像的顏色。
Image(systemName: "star")
.foregroundStyle(.orange)
圖片
foregroundStyle() 修飾符可以采用任何 ShapeStyle,包括漸變,這為我們的符號圖像提供了廣泛的自定義可能性。在這個例子中,星形符號使用了從黃色到紅色的線性漸變,從頂部到底部過渡。
Image(systemName: "star")
.foregroundStyle(
LinearGradient(
colors: [.yellow, .red],
startPoint: .top,
endPoint: .bottom
)
)
圖片
渲染模式
我們可以通過使用不同的渲染模式進一步自定義符號圖像的外觀。SF Symbols有四種不同的渲染模式,這些模式會改變符號的顏色和外觀。一些渲染模式使整個圖標保持相同顏色,而其他模式則允許多種顏色。
要在SwiftUI中設(shè)置符號圖像的首選渲染模式,我們使用 symbolRenderingMode() 修飾符。
單色
單色是默認的渲染模式。在這種模式下,符號的每一層都是相同的顏色。
Image(systemName: "thermometer.snowflake")
.symbolRenderingMode(.monochrome)
分層
分層模式將符號渲染為多個層,每層應(yīng)用不同的不透明度。層次結(jié)構(gòu)和不透明度在每個符號中是預(yù)定義的,但我們?nèi)匀豢梢允褂?nbsp;foregroundStyle() 修飾符自定義顏色。
HStack {
Image(systemName: "thermometer.snowflake")
Image(systemName: "thermometer.snowflake")
.foregroundStyle(.indigo)
}
.symbolRenderingMode(.hierarchical)
symbolRenderingMode() 修飾符既可以直接應(yīng)用于圖像視圖,也可以通過將其應(yīng)用于包含多個符號圖像的父視圖來在環(huán)境中設(shè)置。這樣,父元素內(nèi)的所有符號圖像都會受到影響。
圖片
調(diào)色板
調(diào)色板模式允許符號以多層呈現(xiàn),每層具有不同的顏色。這種模式非常適合創(chuàng)建色彩豐富的多層圖標。
Image(systemName: "thermometer.snowflake")
.symbolRenderingMode(.palette)
.foregroundStyle(.blue, .teal, .gray)
我們不需要顯式地指定調(diào)色板呈現(xiàn)模式。如果我們在 foregroundStyle() 修飾符中應(yīng)用多個樣式,則調(diào)色板模式將自動激活。
Image(systemName: "thermometer.snowflake")
.foregroundStyle(.blue, .teal, .gray)
圖片
如果我們?yōu)橐粋€定義了三個層次結(jié)構(gòu)的符號指定兩種顏色,那么第二層和第三層將使用相同的顏色。
Image(systemName: "thermometer.snowflake")
.foregroundStyle(.blue, .gray)
圖片
多色
多色模式使用由 Apple 定義的一組固定顏色渲染符號。在使用多色渲染時,我們無法自定義符號的顏色,它將使用預(yù)定義的顏色。
HStack {
Image(systemName: "thermometer.snowflake")
Image(systemName: "thermometer.sun.fill")
}
.symbolRenderingMode(.multicolor)
圖片
值得注意的是,由于這些顏色是固定的,它們不適應(yīng)明暗模式。例如,我們的溫度計符號具有白色輪廓,在白色背景上是不可見的。
并非所有符號都支持每種呈現(xiàn)模式。圖層較少的符號在不同模式下看起來可能相同,分層和調(diào)色板模式看起來類似于單色。
可變值
在 SwiftUI 中顯示符號圖像時,我們可以提供一個 0.0 到 1.0 之間的可選值,渲染的圖像可以使用它來自定義外觀。如果符號不支持可變值,此參數(shù)無效。我們應(yīng)該在 SF Symbols 應(yīng)用程序中檢查哪些符號支持可變值。
HStack {
Image(systemName: "speaker.wave.3", variableValue: 0)
Image(systemName: "speaker.wave.3", variableValue: 0.3)
Image(systemName: "speaker.wave.3", variableValue: 0.6)
Image(systemName: "speaker.wave.3", variableValue: 0.9)
}
圖片
可變值可以表示一個隨著時間變化的特性,例如容量或強度。這使得符號的外觀可以根據(jù)應(yīng)用程序的狀態(tài)動態(tài)變化。
struct ContentView: View {
@State private var value = 0.5
var body: some View {
VStack {
Image(
systemName: "speaker.wave.3",
variableValue: value
)
Slider(value: $value, in: 0...1)
.padding()
}
.padding()
}
}
在這個例子中,符號 speaker.wave.3 根據(jù) Slider 提供的值改變其外觀。
圖片
我們應(yīng)該使用可變值來傳達狀態(tài)的變化,例如音量、電池電量或信號強度,為用戶提供動態(tài)狀態(tài)的清晰視覺表示。為了傳達深度和視覺層次,我們應(yīng)該使用分層渲染模式,它可以提升某些圖層,并區(qū)分符號內(nèi)的前景和背景元素。
設(shè)計變體
符號可以有不同的設(shè)計變體,例如填充和斜杠,以幫助傳達特定的狀態(tài)和操作。斜杠變體可以表示項目或操作不可用,而填充變體可以表示選擇。
在 SwiftUI 中,我們可以使用 symbolVariant() 修飾符來應(yīng)用這些變體。
HStack {
Image(systemName: "heart")
Image(systemName: "heart")
.symbolVariant(.slash)
Image(systemName: "heart")
.symbolVariant(.fill)
}
不同的符號變體用于各種設(shè)計目的。輪廓變體在工具欄、導航欄和列表中非常有效,而填充變體則用于強調(diào)選擇的狀態(tài)。
HStack {
Image(systemName: "heart")
.symbolVariant(.circle)
Image(systemName: "heart")
.symbolVariant(.square)
Image(systemName: "heart")
.symbolVariant(.rectangle)
}
不同的符號變體具有不同的設(shè)計用途。輪廓變體在工具欄、導航欄和列表中非常有效,因為這些地方通常會與文本一起顯示符號。將符號封裝在圓形或方形等形狀中可以增強其可讀性,特別是在較小尺寸下。填充變體由于其實心區(qū)域,使符號更具視覺強調(diào)性,非常適合用于 iOS 標簽欄、滑動操作以及指示選擇的強調(diào)顏色場景。
在許多情況下,顯示符號的視圖會自動選擇合適的變體。例如,iOS 標簽欄通常使用填充變體,而導航欄則偏好輪廓變體。這種自動選擇確保符號在不同上下文中有效使用,而無需明確指定。
示例代碼
import SwiftUI
struct ContentView: View {
@State private var value = 0.5
var body: some View {
VStack {
Image(
systemName: "speaker.wave.3",
variableValue: value
)
.symbolRenderingMode(.hierarchical)
.foregroundStyle(.blue)
Slider(value: $value, in: 0...1)
.padding()
}
.padding()
}
}
運行 Demo
- 打開Xcode并創(chuàng)建一個新的 SwiftUI 項目。
- 將上述代碼粘貼到 ContentView.swift 文件中。
- 運行項目,查看效果。
結(jié)論
在SwiftUI中增強符號圖像可以顯著改善應(yīng)用程序的外觀和感覺。通過調(diào)整大小、顏色、渲染模式、可變值和設(shè)計變體,我們可以創(chuàng)建使應(yīng)用程序更直觀和視覺吸引力的圖標。SwiftUI使這些調(diào)整變得簡單易行,使我們能夠輕松實現(xiàn)和改進這些自定義以提供更好的用戶體驗。