SwiftUI Modifier 怎麼用?實作範例一次看

💬 這篇文章是我參加 2024 iThome 鐵人賽 時寫的,現在整理過後,重新放上部落格啦!
昨天我們把基本的 UI 元件玩過一輪,今天則是來動手調整它們的樣子啦!
我們常常會在 .padding()、.background()、.cornerRadius() 這些東西前後加一堆點來點去,那這些 modifier 到底是什麼?又該怎麼搭配用才不會畫面崩壞?這篇我邊寫邊試,把目前用過的 View Modifier 整理一下~
View Modifier 是什麼?
簡單來講,就是一堆可以改變 UI 外觀或行為的設定方法。
加上去後,畫面就會跟著變,像幫 UI 穿衣服一樣可以一層一層疊上去。
像這段:
Text("Hello, world!")
.padding()
.border(Color.black)就會讓文字四周留出空間、再加一圈邊框。
但如果把 .border() 放在 .padding() 前面,結果就不一樣了。
Text("Hello, world!")
.border(Color.black)
.padding()
這就是 SwiftUI 的小陷阱——Modifier 的順序會影響畫面呈現!
所以不只要記得有哪些 Modifier,更要搞清楚它們出現的順序。
Modifier 重點整理(附練習紀錄)
以下是我試用過的幾個常見 View Modifier,也順便記一下每個的重點。
1. padding()
設定元件四周的空間。可以不帶參數,也可以指定方向或間距大小。
搭配 .border(Color.black) 一起用會更明顯看到效果。
這個 Modifier 有幾種常見寫法,我自己實測的整理如下:
1. 不加參數:四周都留一樣的邊距
Text("Hello, world!")
.padding()
.border(Color.black)這是最基本的寫法,會在文字四邊都加上一圈預設大小的邊距。
2. 指定方向 .padding(.top):只對一邊加邊距
Text("Hello, world!")
.padding(.leading)
.border(Color.black)
這會只在「左邊」加上內距,其他三邊保持原樣。
方向參數包含 .top、.bottom、.leading(左)、.trailing(右)。
3. 同時指定多個方向 .padding([.top, .leading])
Text("Hello, world!")
.padding([.top, .leading])
.border(Color.black)
這會在「上」和「左」同時加上內距,其他兩邊不變。
4. 指定數值 .padding(20):四邊都用同樣大小
Text("Hello, world!")
.padding(20)
.border(Color.black)
這段是把四邊都設為 20 點的內距,比預設再大一點,畫面看起來更鬆。
5. 指定方向 + 數值 .padding(.top, 30)
Text("Hello, world!")
.padding(.top, 30)
.border(Color.black)
這段把文字的上方設定 30 點的內距。如果還想加上其他方向的內距,例如在上方設定 30 點內距,同時在左邊設定 10 點內距,我們可以這樣寫:
Text("Hello, world!")
.padding(.top, 30)
.padding(.leading, 10)
.border(Color.black)
這種寫法可以讓你對不同邊設不同數值,排版更有彈性!
2. background()
設定背景色、背景圖、甚至放別的 View 當背景都可以。
這邊示範幾種用法:
1. 單一顏色背景
最常見的用法是在 background() 中加入顏色,這樣可以為元件設定單一顏色作為背景。
Text("Hello, world!")
.padding()
.background(Color.blue)
.border(Color.black)
可以看到這段程式碼在文字周圍加上藍色背景。
2. 使用圖片作為背景
除了使用顏色作為背景外,也可以使用圖片作為背景
Text("Hello, world!")
.padding()
.background(Image("backgroundImage"))
.border(Color.black)在 background() 中加入 Image(“圖片名稱”),即可將圖片設為背景。為了省去尋找圖片的時間,我這邊直接使用 SF Symbols 圖案作為背景,方便又快速!
Text("Hello, world!")
.padding()
.background(
Image(systemName: "star.fill")
.resizable()
.scaledToFit()
)
這樣我們就看到一個星形圖案設為文字的背景啦~
為了讓星星符合大小,我多加上以下兩個 Modifiers:
resizable()讓圖片自由調整大小。scaledToFit()讓圖片按比例縮放並且符合元件大小。
SF Symbol 參考資料:
3. 使用漸層色作為背景
既然可以使用單一顏色作為背景,當然也可以用漸層色當作背景啦~
Text("Hello, world!")
.padding()
.background(
LinearGradient(
gradient: Gradient(colors: [Color.blue, Color.purple]),
startPoint: .top,
endPoint: .bottom
)
)
.border(Color.black)
我設定了從藍色漸變到紫色的背景。LinearGradient 是用來設置漸層色,而 startPoint 和 endPoint 則是用來控制漸層的方向。
4. 使用其他元素作為背景
剛剛介紹了顏色、圖片當作背景,其實還可以使用其他 UI 元素作為背景唷!
Text("Hello, world!")
.padding()
.background(Circle().fill(Color.green))
.border(Color.black)
這次我設定在文字後面加上一個綠色的圓形作為背景。
設定背景對齊方式
背景只能置中對齊也未免太無趣,我們可以透過 alignment 參數,對於背景內容的對齊方式進行設定。
Text("Hello, world!")
.padding()
.background(
Image(systemName: "star.fill")
.resizable()
.scaledToFit(),
alignment: .center
)
.border(Color.black)
這樣我們就可以得到一個星形圖案作為文字的背景,而且可以看到它是對齊到左邊(leading),是不是很好玩呢?
3. foregroundColor()
foregroundColor() 是用來讓文字更改顏色。
Text("Hello, world!")
.padding()
.foregroundColor(.white)
.background(Color.black)
.border(Color.black)
這樣就能得到一段白色文字配黑色背景的效果。
雖然 foregroundColor() 也還能用,但已經不太建議了。
改用 foregroundStyle() 可以做更多變化,像漸層字色也能支援。
foregroundStyle()
foregroundStyle() 和 foregroundColor() 類似,但它可以進行更豐富的設定。單一顏色、漸層色,甚至多種顏色都難不倒它!
Text("Hello, world!")
.padding()
.foregroundStyle(Color.blue)
.background(Color.black)
.border(Color.black)
我們使用 foregroundStyle() 將文字顏色設為藍色,但它能做的不只這樣唷~
使用漸層色作為樣式
我們來試試漸層色吧!
Text("Hello, world!")
.padding()
.foregroundStyle(
LinearGradient(
gradient: Gradient(colors: [.blue, .purple]),
startPoint: .top,
endPoint: .bottom
)
)
.background(Color.gray)
.border(Color.black)為了怕漸層色看不太清楚,我們放大一點。

看到了嗎?我設定文字顏色為從藍色到紫色的漸層效果,使得文字更多樣化了!
4. cornerRadius()
幫元件加上圓角效果。常用在 button、卡片樣式。
Button("Tap me!") {
print("Button was tapped!")
}
.padding()
.background(Color.green)
.foregroundColor(.white)
.cornerRadius(10)
這樣我們得到含有內距,並且帶有綠色背景和白色文字的一個圓角按鈕。
5. shadow()
加陰影,看起來比較有立體感。
Button("Tap me!") {
print("Button was tapped!")
}
.padding()
.background(Color.green)
.foregroundColor(.white)
.cornerRadius(10)
.shadow(radius: 10)
看起來更有立體感了!
6. opacity()
調整透明度,讓畫面更柔和或是製造淡出效果。
Button("Tap me!") {
print("Button was tapped!")
}
.padding()
.background(Color.green)
.foregroundColor(.white)
.cornerRadius(10)
.shadow(radius: 10)
.opacity(0.5)
忍術隱身術(誤,其實只有變淡 50% 啦XD
7. frame()
調整元件的寬、高、對齊方式,是版面配置的好夥伴。
Button("Tap me!") {
print("Button was tapped!")
}
.padding()
.frame(width: 200, height: 100, alignment: .center)
.background(Color.green)
.foregroundColor(.white)
.cornerRadius(10)
.shadow(radius: 10)
我為 Button 元件設定寬 200、高 100,並讓它置中對齊。
多個 Modifier 的組合
SwiftUI 的魅力之一,就是 Modifier 可以隨意疊加。
只要順序沒錯、不要打架,效果都能一層層套上去。
像這段就是全部加一輪:
Text("SwiftUI Modifiers")
.padding()
.background(Color.blue)
.foregroundColor(.white)
.cornerRadius(10)
畫面就變得很完整、有邊距、有背景、有圓角,超適合拿來做標籤或按鈕。
小結一下
今天主要是在試各種常見的 View Modifier,也更能理解它們之間的關係。
Modifier 用得好,畫面就會乾淨又有設計感。
明天會繼續研究一些進階的 Modifier 應用方式,慢慢往 UI 魔法師邁進(希望啦~ XD



