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

💬 這篇文章是我參加 2024 iThome 鐵人賽 時寫的,現在整理過後,重新放上部落格啦!

昨天我們把基本的 UI 元件玩過一輪,今天則是來動手調整它們的樣子啦!
我們常常會在 .padding().background().cornerRadius() 這些東西前後加一堆點來點去,那這些 modifier 到底是什麼?又該怎麼搭配用才不會畫面崩壞?這篇我邊寫邊試,把目前用過的 View Modifier 整理一下~

View Modifier 是什麼?

簡單來講,就是一堆可以改變 UI 外觀或行為的設定方法。
加上去後,畫面就會跟著變,像幫 UI 穿衣服一樣可以一層一層疊上去。

像這段:

Swift
Text("Hello, world!")
    .padding()
    .border(Color.black)

就會讓文字四周留出空間、再加一圈邊框。
但如果把 .border() 放在 .padding() 前面,結果就不一樣了。

Swift
Text("Hello, world!")
    .border(Color.black)
    .padding()
Modifier放置位置不同對照圖
Modifier放置位置不同對照圖

這就是 SwiftUI 的小陷阱——Modifier 的順序會影響畫面呈現
所以不只要記得有哪些 Modifier,更要搞清楚它們出現的順序。

Modifier 重點整理(附練習紀錄)

以下是我試用過的幾個常見 View Modifier,也順便記一下每個的重點。

1. padding()

設定元件四周的空間。可以不帶參數,也可以指定方向或間距大小。
搭配 .border(Color.black) 一起用會更明顯看到效果。

這個 Modifier 有幾種常見寫法,我自己實測的整理如下:

1. 不加參數:四周都留一樣的邊距
Swift
Text("Hello, world!")
    .padding()
    .border(Color.black)

這是最基本的寫法,會在文字四邊都加上一圈預設大小的邊距。

2. 指定方向 .padding(.top):只對一邊加邊距
Swift
Text("Hello, world!")
    .padding(.leading)
    .border(Color.black)
設定 padding leading
設定 padding leading

這會只在「左邊」加上內距,其他三邊保持原樣。
方向參數包含 .top.bottom.leading(左)、.trailing(右)。

3. 同時指定多個方向 .padding([.top, .leading])
Swift
Text("Hello, world!")
    .padding([.top, .leading])
    .border(Color.black)
padding top 和 leading
padding top 和 leading

這會在「上」和「左」同時加上內距,其他兩邊不變。

4. 指定數值 .padding(20):四邊都用同樣大小
Swift
Text("Hello, world!")
    .padding(20)
    .border(Color.black)
設定padding 20點
設定padding 20點

這段是把四邊都設為 20 點的內距,比預設再大一點,畫面看起來更鬆。

5. 指定方向 + 數值 .padding(.top, 30)
Swift
Text("Hello, world!")
    .padding(.top, 30)
    .border(Color.black)
設定padding top 30點
設定padding top 30點

這段把文字的上方設定 30 點的內距。如果還想加上其他方向的內距,例如在上方設定 30 點內距,同時在左邊設定 10 點內距,我們可以這樣寫:

Swift
Text("Hello, world!")
    .padding(.top, 30)
    .padding(.leading, 10)
    .border(Color.black)
設定padding top 和 leading 30點
設定padding top 和 leading 30點

這種寫法可以讓你對不同邊設不同數值,排版更有彈性!

參考資料:func padding(Edge.Set, CGFloat?) -> some View

2. background()

設定背景色、背景圖、甚至放別的 View 當背景都可以。

這邊示範幾種用法:

1. 單一顏色背景

最常見的用法是在 background() 中加入顏色,這樣可以為元件設定單一顏色作為背景。

Swift
Text("Hello, world!")
    .padding()
    .background(Color.blue)
    .border(Color.black)
background設為blue

可以看到這段程式碼在文字周圍加上藍色背景。

2. 使用圖片作為背景

除了使用顏色作為背景外,也可以使用圖片作為背景

Swift
Text("Hello, world!")
    .padding()
    .background(Image("backgroundImage"))
    .border(Color.black)

background() 中加入 Image(“圖片名稱”),即可將圖片設為背景。為了省去尋找圖片的時間,我這邊直接使用 SF Symbols 圖案作為背景,方便又快速!

Swift
Text("Hello, world!")
    .padding()
    .background(
        Image(systemName: "star.fill")
            .resizable()
            .scaledToFit()
    )
background 設定 image

這樣我們就看到一個星形圖案設為文字的背景啦~

為了讓星星符合大小,我多加上以下兩個 Modifiers:

  • resizable() 讓圖片自由調整大小。
  • scaledToFit() 讓圖片按比例縮放並且符合元件大小。

SF Symbol 參考資料:

3. 使用漸層色作為背景

既然可以使用單一顏色作為背景,當然也可以用漸層色當作背景啦~

Swift
Text("Hello, world!")
    .padding()
    .background(
        LinearGradient(
            gradient: Gradient(colors: [Color.blue, Color.purple]),
            startPoint: .top,
            endPoint: .bottom
        )
    )
    .border(Color.black)
background設為LinearGradient

我設定了從藍色漸變到紫色的背景。LinearGradient 是用來設置漸層色,而 startPointendPoint 則是用來控制漸層的方向。

4. 使用其他元素作為背景

剛剛介紹了顏色、圖片當作背景,其實還可以使用其他 UI 元素作為背景唷!

Swift
Text("Hello, world!")
    .padding()
    .background(Circle().fill(Color.green))
    .border(Color.black)
background設為circle

這次我設定在文字後面加上一個綠色的圓形作為背景。

設定背景對齊方式

背景只能置中對齊也未免太無趣,我們可以透過 alignment 參數,對於背景內容的對齊方式進行設定。

Swift
Text("Hello, world!")
    .padding()
    .background(
        Image(systemName: "star.fill")
            .resizable()
            .scaledToFit(),
        alignment: .center
    )
    .border(Color.black)
background設為image並設定leading

這樣我們就可以得到一個星形圖案作為文字的背景,而且可以看到它是對齊到左邊(leading),是不是很好玩呢?

參考資料:利用 SwiftUI 的 background 設定背景顏色,背景圖片,漸層背景 & 圓角背景

3. foregroundColor()

foregroundColor() 是用來讓文字更改顏色。

Swift
Text("Hello, world!")
    .padding()
    .foregroundColor(.white)
    .background(Color.black)
    .border(Color.black)
設定foregroundColor

這樣就能得到一段白色文字配黑色背景的效果。

雖然 foregroundColor() 也還能用,但已經不太建議了。
改用 foregroundStyle() 可以做更多變化,像漸層字色也能支援。

foregroundStyle()

foregroundStyle()foregroundColor() 類似,但它可以進行更豐富的設定。單一顏色、漸層色,甚至多種顏色都難不倒它!

Swift
Text("Hello, world!")
    .padding()
    .foregroundStyle(Color.blue)
    .background(Color.black)
    .border(Color.black)
設定foregroundStyle

我們使用 foregroundStyle() 將文字顏色設為藍色,但它能做的不只這樣唷~

使用漸層色作為樣式

我們來試試漸層色吧!

Swift
Text("Hello, world!")
    .padding()
    .foregroundStyle(
        LinearGradient(
            gradient: Gradient(colors: [.blue, .purple]),
            startPoint: .top,
            endPoint: .bottom
        )
    )
    .background(Color.gray)
    .border(Color.black)

為了怕漸層色看不太清楚,我們放大一點。

foregroundStyle 設定 LinearGradient
foregroundStyle 設定 LinearGradient

看到了嗎?我設定文字顏色為從藍色到紫色的漸層效果,使得文字更多樣化了!

4. cornerRadius()

幫元件加上圓角效果。常用在 button、卡片樣式。

Swift
Button("Tap me!") {
    print("Button was tapped!")
}
  .padding()
  .background(Color.green)
  .foregroundColor(.white)
  .cornerRadius(10)
cornerRadius
設定cornerRadius

這樣我們得到含有內距,並且帶有綠色背景和白色文字的一個圓角按鈕。

5. shadow()

加陰影,看起來比較有立體感。

Swift
Button("Tap me!") {
    print("Button was tapped!")
}
    .padding()
    .background(Color.green)
    .foregroundColor(.white)
    .cornerRadius(10)
    .shadow(radius: 10)
shadow
設定 shadow

看起來更有立體感了!

6. opacity()

調整透明度,讓畫面更柔和或是製造淡出效果。

Swift
Button("Tap me!") {
    print("Button was tapped!")
}
    .padding()
    .background(Color.green)
    .foregroundColor(.white)
    .cornerRadius(10)
    .shadow(radius: 10)
    .opacity(0.5)
opacity
設定 opacity

忍術隱身術(誤,其實只有變淡 50% 啦XD

7. frame()

調整元件的寬、高、對齊方式,是版面配置的好夥伴。

Swift
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)
frame
設定 frame

我為 Button 元件設定寬 200、高 100,並讓它置中對齊。

多個 Modifier 的組合

SwiftUI 的魅力之一,就是 Modifier 可以隨意疊加。
只要順序沒錯、不要打架,效果都能一層層套上去。

像這段就是全部加一輪:

Swift
Text("SwiftUI Modifiers")
    .padding()
    .background(Color.blue)
    .foregroundColor(.white)
    .cornerRadius(10)
結合Modifiers的使用
結合Modifiers的使用

畫面就變得很完整、有邊距、有背景、有圓角,超適合拿來做標籤或按鈕。

小結一下

今天主要是在試各種常見的 View Modifier,也更能理解它們之間的關係。
Modifier 用得好,畫面就會乾淨又有設計感。
明天會繼續研究一些進階的 Modifier 應用方式,慢慢往 UI 魔法師邁進(希望啦~ XD

參考資料:ViewModifier | Apple Developer Documentation

繼續看第六天 👉 [2024鐵人賽]Day 6: 挖掘 SwiftUI 的進階 View Modifiers

分享這篇文章

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *