第 3 章
圖片與標籤的處理

現在你應該對於 SwiftUI 有了基本概念,並了解如何顯示文字內容,本章我們來看如何顯示圖片。我們也會學習標籤(Label)的用法。

除了文字之外,圖片是 iOS App 開發的另外一個基本元件。SwiftUI 提供一個名為 Image 的視圖,來讓開發者將圖片渲染在螢幕上。首前一章的內容相似,我會建立一個簡單的 App,以示範如何進行圖片的處理。本章可歸納為以下幾個主題:

  • 什麼是SF Symbol,以及如何顯示一個系統圖片?
  • 如何顯示我們自己的圖片?
  • 如何調整圖片大小?
  • 如何使用 ignoresSafeArea 來顯示一個全螢幕的圖片?
  • 如何建立一個圓形圖片?
  • 如何在圖片上應用重疊?

使用 SwiftUI 來建立新專案

首先,開啟Xcode 並使用「App」模板( 在 iOS 分類下),來建立一個新專案。輸入專案的名稱,並設定為「SwiftUIImage」。關於組織名稱,你可以設定為你自己公司或組織名稱, 同樣的,我使用「com.appcoda」,但你可以使用自己的值。要使用SwiftUI 的話,請確認在「User Interface」選項中選取 「SwiftUI」然後點擊「Next」,選取要建立專案的資料夾, 如圖 3.1 所示。

圖 3.1. 建立一個新專案
圖 3.1. 建立一個新專案

專案儲存完成之後,Xcode 即會載入 ContentView.swift 檔,並顯示一個「設計/ 預覽」畫布,如圖 3.2 所示。

圖 3.2. 預覽所產生的程式
圖 3.2. 預覽所產生的程式

SF Symbols 介紹

SF Symbols 7 是一個包含超過 6,900 個符號的圖示庫,專為與 Apple 各平台的系統字體 San Francisco 無縫整合而設計。這些符號提供九種字重和三種比例,能自動與文字對齊,並可匯出後以向量圖形工具編輯,製作具有相同設計風格與無障礙特性的自訂符號。SF Symbols 7 引入了 Draw 動畫、可變渲染效果、強化的 Magic Replace、漸層支援,以及數百個全新的符號。

在介紹如何在畫面上顯示圖片之前,我們先來了解圖片的來源。你可以為 App 提供自己的圖片,但從 iOS 13 開始,Apple 推出了名為 SF Symbols 的大型系統圖示集,開發者可以在任何 App 中使用。隨著 iOS 26 的發佈,Apple 進一步改進了這個圖示集,推出 SF Symbols 7,其中包含超過 6,900 個符號,並支援多種動畫效果。

這些圖示之所以被稱為「符號」,是因為它們能與 Apple 內建的 San Francisco 系統字體無縫整合。它的一大優點是——你不需要額外安裝任何資源就能在 App 中使用這些符號。只要裝置執行的是 iOS 13 或更新版本,就能直接使用。

不過需要注意的是,不同版本的 iOS 支援的符號數量並不相同。雖然基本符號集可以在 iOS 13 及以上版本使用,但最新的 SF Symbols 符號則僅限於 iOS 和 iPadOS 26.0 以上的系統。這意味著如果你想在 App 中使用最新符號,就必須考慮 App 的最低支援版本,並為舊系統使用者提供替代方案。

透過運用 SF Symbols,你可以讓 App 的圖示在所有 Apple 平台上保持一致且原生的外觀,同時享有良好的可縮放性與無障礙特性。不過,在整合新版符號時,別忘了考量版本相容性,確保使用體驗一致。

當要使用這些標誌時,你需要準備的是找到標誌名稱。由於有超過 6,900 個符號可供使用,Apple 釋出一個名為 SF Symbols (https://developer.apple.com/sf-symbols/) 個標誌可以讓你使用,因此你可以很容易地找到你要的標誌來配合你的設計。我極力推薦你在進行下一節之前,先安裝這個 App。

圖 3.3 SF Symbols App
圖 3.3 SF Symbols App

顯示系統圖片

想要在螢幕上顯示系統圖片的話,你可以初始化一個 Image 視圖,加上 systemName 參數,如下所示:

Image(systemName: "cloud.heavyrain")

這將會建立一個圖片視圖,並載入指定的系統圖片。如前所述,SF Symbols 與 San Francisco 字型無縫整合。你可以很容易地應用 font 修飾器來進行圖片的縮放。

Image(systemName: "cloud.heavyrain")
    .font(.system(size: 100))

你可以變更字型大小來觀察圖片的反應,如圖 3.4 所示。

圖 3.4. 顯示系統圖片
圖 3.4. 顯示系統圖片

同樣的,因為系統圖片實際上是一個字型,你可以應用其他的修飾器如之前所學過的 foregroundColor,來變更它的外觀。

例如:要變更顏色為藍色,你可以撰寫程式如下:

Image(systemName: "cloud.heavyrain")
    .font(.system(size: 100))
    .foregroundStyle(.blue)

要加入一個下拉式陰影效果(drop shadow effect ),你只需要使用 shadow 修飾器:

Image(systemName: "cloud.heavyrain")
    .font(.system(size: 100))
    .foregroundStyle(.blue)
    .shadow(color: .gray, radius: 10, x: 0, y: 10)

使用自己的圖片

在前面,我們使用了Apple 內建的圖片。不過,你可能會在App 中使用自己的圖片。那麼,要如何使用 Image 視圖來載入圖片呢?

Note: 你可以任意使用自己的圖片,若是你沒有合適的圖片,也可以至 unsplash.com 下載圖片 (https://unsplash.com/photos/Q0-fOL2nqZc) ,以方便繼續後面的內容。圖片下載完成之後,請將檔名改成「paris.jpg」。

在你的專案能夠使用圖片之前,首先你必須先將圖片匯入素材目錄( Asset Catalog ), 也就是 Assets。假設你已經準備好圖片(paris.jpg ),按下 command+0 鍵來開啟專案導覽器(Project Navigator ),並選取 Assets。現在開啟 Finder,並將圖片拖曳至大綱視圖(Outline View ),如圖 3.5 所示。

圖 3.5 將圖片加至素材目錄
圖 3.5 將圖片加至素材目錄

如果你是 iOS App 開發新手,這個素材目錄是你儲存應用程式資源如圖片、顏色與資料的地方。當你將圖片放入素材目錄時,你可以參照它的名稱來下載圖片。另外,你可以設定要載入圖片的裝置(例如:只限 iPhone )。

要在螢幕上顯示圖片,可撰寫程式如下:

Image("paris")

你只需要指定圖片名稱,可在預覽畫布中見到圖片。然而,由於圖片是高解析度圖片( 4437×6656 像素),你只能見到部分圖片,如圖 3.6 所示。

圖 3.6. 載入自訂的圖片
圖 3.6. 載入自訂的圖片

調整圖片大小

那麼,如何調整圖片呢?你可以使用 resizable 修飾器,如下所示:

Image("paris")
    .resizable()

預設上,圖片大小調整是使用「延伸」(stretch )模式。這表示原始圖片將會被放大到填滿整個螢幕畫面(除了頂部與底部區域之外),如圖 3.7 所示。

圖 3.7. 以resizable 修飾器調整圖片大小
圖 3.7. 以resizable 修飾器調整圖片大小

技術上而言,這個圖片填滿了整個 iOS 所定義的安全區域(Safe Area )。安全區域的觀念已經存在一段頗長的時間了,定義為安全佈局UI 元件的視圖區域。舉例而言,如圖 3.7 所示,這個安全區域不包含頂部列(Top Bar )(也就是狀態列)與底部列(Bottom Bar ) 的區域。安全區域可以避免你不小心隱藏了系統 UI 元件,例如:狀態列(Status Bar )、導覽列(Navigation Bar )與標籤列(Tab Bar )。

既然我們正好說到這件事, 若是你想要顯示全螢幕圖片, 你可以設定 ignoringSafeArea 修飾器來忽略安全區域,如圖 3.8 所示。

圖 3.8 忽略安全區域
圖 3.8 忽略安全區域

你可以針對特定的邊緣來忽略安全區域,例如:要忽略底部邊緣的安全區域,你只要傳送 .bottom 作為參數即可:

.ignoresSafeArea(.container, edges: .bottom)

Aspect Fit 與 Aspect Fill

如果你看一下前一小節這兩張圖片,並與原來的做比對,你應該會發現長寬比(aspect ratio )有些失真。這個延伸模式不會去管圖片的長寬比,它只是將每一邊延伸來填滿安全區域而已。如圖 3.9 所示,要保持原來的長寬比的話,你可以像這樣應用 scaledToFit 修飾器:

Image("paris")
    .resizable()
    .scaledToFit()
 圖 3.9 縮放圖片保持原來的長寬比
圖 3.9 縮放圖片保持原來的長寬比

另外,你可以使用 aspectRatio 修飾器,並設定內容模式(Content Mode)為. fit,這會達成同樣的結果。

Image("paris")
    .resizable()
    .aspectRatio(contentMode: .fit)

在某些情況下,你想要圖片的長寬比保持一樣,但儘可能地延伸,則你可以應用 .fill 內容模式:

Image("paris")
    .resizable()
    .aspectRatio(contentMode: .fill)

我們試著來限制圖片的大小,這有助於你對這兩種模式能更了解。frame 修飾器可以讓你控制視圖的大小。舉例而言,設定框架(frame )的寬度為「300 點」,圖片的寬度將會限制在 300 點,如圖 3.10 所示。

圖 3.10. 利用 frame 控制圖片的寬度
圖 3.10. 利用 frame 控制圖片的寬度

現在將 Image 程式以下面的程式碼取代:

Image("paris")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 300)

這張圖片會被縮小,但是仍保持原始長寬比。如果你變更內容模式為 .fill,圖片看起來與圖 3.7 幾乎相同,然而當你使用selectable 模式並仔細看圖 3.11,長寬比是維持不變的。

圖 3.11. 使用.fill 內容模式
圖 3.11. 使用.fill 內容模式

你可能會注意到圖片的寬度不是我們想要的,它依然占滿整個螢幕寬度。要正確運作的話,你必須使用 clipped 修飾器來消除視圖額外的部分,如圖 3.12 所示。

圖 3.12. 使用.clipped 來裁切視圖
圖 3.12. 使用.clipped 來裁切視圖

建立圓形圖片

除了將圖片裁切為長方形之外,SwiftUI 提供其他修飾器來讓你將圖片裁成不同的形狀,例如:圓形。舉例而言,如果你想要建立圓形圖片,你可以像這樣使用 clipShape 修飾器:

Image("paris")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 300)
    .clipShape(Circle())

另外,你可以使用 .circle 代替 Circle()

Image("paris")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 300)
    .clipShape(.circle)

這裡我們指定將圖片裁成圓形。你可以傳送不同參數(如 Ellipse() )來建立不同形狀的圖片,圖 3.13 為一些範例。

圖 3.13. 使用.clipShape 修飾器來建立不同形狀的圖片
圖 3.13. 使用.clipShape 修飾器來建立不同形狀的圖片

不透明度的調整

SwiftUI 內建了名為 opacity 的修飾器,你可以使用這個修飾器來控制圖片(或者任何視圖)的不透明度。你傳送一個介於0 與1 的值來指定圖片的不透明度。這裡,「0」代表視圖完全透明,「1」則代表完全不透明。

舉例而言,如果你對圖片視圖應用了opacity 修飾器,並設定其值為「0.5」,則這個圖片將會呈現半透明(partially transparent ),如圖 3.14 所示。

圖 3.14 調整不透明度為50 %
圖 3.14 調整不透明度為50 %

應用圖片重疊

在設計App 時,有時你需要將另一個圖片或文字分層放置在圖片視圖之上。SwiftUI 框架提供一個名為「overlay」的修飾器給開發者,來將圖片進行重疊(Overlay ),例如:你要重疊一個系統圖片(如 heart.fill )至目前的圖片,你可以撰寫程式如下:

Image("paris")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .frame(width: 300)
    .clipShape(.circle)
    .overlay(
        Image(systemName: "heart.fill")
            .font(.system(size: 50))
            .foregroundColor(.black)
            .opacity(0.5)
    )

程式中的 .overlay 修飾器帶入一個 View 作為參數。在上列的程式中,我們建立其他的圖片(如 heart.fill ),並將其重疊在目前圖片(如 Paris )之上,如圖 3.15 所示。

圖 3.15 在目前的圖片上應用重疊
圖 3.15 在目前的圖片上應用重疊

事實上,你可以採用任何視圖來做重疊。例如:你可以重疊一個 Text 視圖在圖片之上。程式寫法如下:

Image("paris")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .overlay(

        Text("If you are lucky enough to have lived in Paris as a young man, then wherever you go for the rest of your life it stays with you, for Paris is a moveable feast.\n\n- Ernest Hemingway")
            .fontWeight(.heavy)
            .font(.system(.headline, design: .rounded))
            .foregroundStyle(.white)
            .padding()
            .background(Color.black)
            .cornerRadius(10)
            .opacity(0.8)
            .padding(),

        alignment: .top

    )

overlay 修飾器,你只需要建立一個 Text 視圖,而這個文字視圖將會作為圖片上的重疊物件。我相信你已經熟悉了 Text 視圖的修飾器,我們在前面的章節已經有介紹過。我們只是變更字型與顏色,除此之外,我們加入了間距與背景顏色。另外,要特別說明的是 alignment 參數,對於 overlay 修飾器,你可以提供一個可選值(Optional Value )來調整視圖的對齊。預設是置中對齊,這裡我們想要將文字重疊於圖片之上,如圖 3.16 所示。你可以自己將值變更為「.center」或者「.bottom」,來看看結果為何。

圖3.16 在目前的圖片上應用重疊
圖3.16 在目前的圖片上應用重疊

以重疊來使圖片變暗

你不止可以重疊圖片或文字在另一張圖片上,你也可以應用重疊來使圖片變暗。將 Image 程式以下列程式替代,並看一下效果:

Image("paris")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .overlay(
        Rectangle()
            .foregroundStyle(.black)
            .opacity(0.4)
    )

我們在圖片上畫一個矩形(Rectangle ),並將其前景色設定為「black」。為了達到變暗(darken )效果,我們設定不透明度為「0.4」,也就是 40% 的不透明度,圖片現在應該變暗了。

也可以將程式重寫如下完成一樣的效果:

Image("paris")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .overlay(
        Color.black
            .opacity(0.4)
    )

在 SwiftUI,正好 Color 也是一個視圖,因此我們可以使用 Color.black 作為上層來將下層的圖片變暗。

當你想要將一些亮色文字重疊在太亮的圖片上時,這個技術尤其有用。我們將 Image 程式替換如下:

Image("paris")
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(width: 300)
    .overlay(
        Color.black
            .opacity(0.4)
            .overlay(
                Text("Paris")
                    .font(.largeTitle)
                    .fontWeight(.black)
                    .foregroundStyle(.white)
                    .frame(width: 200)
            )
    )

如前所述,這個 overlay 修飾器不限於 Image,你也可以將它應用在其他視圖上。在上列的程式中,我們使用「Color.black」來使圖片變暗。此外,我們也重疊並放置了一個 Text。如果你的步驟都正確的話,你應該會見到一個「Paris」的文字放置在深色的圖片上面,如圖 3.17 所示。

圖 3.17. 使圖片變暗並應用文字重疊
圖 3.17. 使圖片變暗並應用文字重疊

使用有顏色的 SF Symbols

自 iOS 15 推出後,SF Symbols 提供四種渲染模式,可以將顏色應用於符號。 根據所選擇的模式,你可以為符號填上單色或多種顏色。 例如,cloud.sun.rain 是一個支持Palette Rendering 的符號。 你可以對符號應用兩種或多種對比色。 下圖顯示如何使用 SF Symbols 應用程式測試調色板。

圖 3.18. 在 SF Symbols 中使用調色板
圖 3.18. 在 SF Symbols 中使用調色板

在 SwiftUI 中,你可以加入 symbolRenderingMode 修飾器來更改模式。 要建立具有多種顏色的相同符號,你可以編寫如下程式碼:

Image(systemName: "square.and.arrow.down")
    .symbolRenderingMode(.palette)
    .foregroundStyle(.indigo, .yellow, .gray)
    .font(.system(size: 200))

我們在程式碼中指定使用palette 模式,然後使用foregroundStyle 修飾器使用顏色。

可變顏色(Variable Colors)

SF Symbols 添加了一個名為 Variable Color 的新功能。 你可以通過更改百分比值來調整符號的顏色。 這在使用某些符號表示進度時特別有用。

當你打開 SF Symbols 應用程式後,請選擇 Variable 類別,並挑選其中一個符號。在檢查器(Inspector)中,你可以點擊 Variable 開關來啟用此功能。當你調整百分比數值時,該符號會根據數值變化而呈現不同的填充效果。

例如,trash.circle 符號:當百分比設為 58% 時,圓環會部分填滿,以顯示進度狀態。

圖 3.19. 在 SF Symbols app 使用 Variable Colors
圖 3.19. 在 SF Symbols app 使用 Variable Colors

可變顏色適用於 SF Symbols 內的每種渲染模式(Rendering mode)。 你可以試試更改為其他渲染模式以查看效果。

至於,要在程式碼中設置百分比值,你可以在建立 Image 視圖時,加入 variableValue 參數並將其與百分比值一起傳遞:

Image(systemName: "slowmo", variableValue: 0.6)
    .symbolRenderingMode(.palette)
    .foregroundStyle(.indigo)
    .font(.largeTitle)

本章小結

在本章中,我介紹了如何以 SwiftUI 處理圖片。SwiftUI 已經讓開發者很容易顯示圖片, 並讓我們使用不同的修飾器來產生各種的圖片效果。如果你是獨立開發者,這些新導入的 SF Symbols 會節省你尋找第三方圖示的時間。

在本章所準備的範例檔中,有完整的專案可以下載:

想更深入學習SwiftUI和下載完整程式碼?你可以從 AppCoda網站購買《精通 SwiftUI》完整電子版。

results matching ""

    No results matching ""