在前一課提到,「字串操作」是程式設計師必備的技能之一,Swift 的字串 String 其實也是物件類型,提供數十種物件屬性與方法,用於字串操作,功能相當齊備。例如我們曾經用 String().count 取得字串的「長度」(字元數),上一課用 String().range() 來搜尋子字串(Substring)。

一個字串最大的長度並沒有限制,只要記憶體容納得了,應該都不會超過 String().count 能計算的上限;至於最小的字串長度,則是空字串 “”,””.count 為0。

在Swift內部,一個字串是由0到任意多個「字元(Character)」所組成,「字元」其實也是資料型態的一種,名為 Character,一個字元值也是用雙引號包含起來,例如 “a”, “東”, “😀”, “¥”...等,Swift 字元是以萬國碼(Unicode)為基礎,任何一個萬國碼字元都可以當作字元值。

本課將學習如何將字串分解,包括斷行、斷句與斷字,將字串分解後,才方便對文字進一步處理,不管是要用添加屬性或用產生動畫,都比較有彈性。

IV-3a 文字斷行

要分解一個字串,所用的物件方法為 .components(),這是一個物件實例的方法,必須用於一個字串變數或常數(也就是字串實例)。

在以下範例4-3a中,我們用微軟的AI機器人「小冰」,上傳上節課所用的泰雅族少女圖片,讓小冰創作一首新詩,再利用 .components(separatedBy: .newlines) 來斷行,將詩句分解成若干行。

// 4-3a 文字斷行 String.components()
// Revised by Heman, 2022/03/25
import PlaygroundSupport
import SwiftUI

let 小冰創作 = """
    天空中有夢人的花瓣飄落
    是頑童嬉鬧快樂的消息
    可愛的葡萄生長在夢中的世界
    
    希望在太陽的頂巔閃耀
    因為人類說我們是朋友
    宛若天空一樣的清明
    
    —— 小冰  2022.3.27
    """

let 詩句 = 小冰創作.components(separatedBy: .newlines)
let 行數 = 詩句.count
print(詩句, "共\\(行數)行")

struct 現代詩選: View {
    @State var 行次: Int = 0
    let 定時器 = Timer.publish(every: 1.5, on: .main, in: .common).autoconnect()
    var body: some View {
        VStack {
            ForEach(詩句.indices, id: \\.self) { 索引 in
                Text(詩句[索引])
                    .foregroundColor(索引 == 行次 ? .white : .purple)
                    .background(索引 == 行次 ? Color.cyan : Color.clear)
                    .font(.system(.title))
            } 
        }
        .onReceive(定時器) { _ in
            行次 = (行次 + 1) % 行數
            if 詩句[行次] == "" {
                行次 = (行次 + 1) % 行數
            }
        }
    }
}

PlaygroundPage.current.setLiveView(現代詩選())

程式一開始,小冰創作.components(separatedBy: .newlines) 會傳回一個陣列,陣列元素是一行詩句,原字串「小冰創作」的值並不受影響:

let 詩句 = 小冰創作.components(separatedBy: .newlines)
let 行數 = 詩句.count
print(詩句, "共\\(行數)行")

控制台輸出如下,注意陣列中有兩個空字串:

["天空中有夢人的花瓣飄落", "是頑童嬉鬧快樂的消息", "可愛的葡萄生長在夢中的世界", "", "希望在太陽的頂巔閃耀", "因為人類說我們是朋友", "宛若天空一樣的清明", "", "—— 小冰 2022.3.27”] 共9行

接下來,就可以用VStack和ForEach將各行詩句排列顯示出來,跟上一課相比,VStack 預設每行置中對齊,而上一課用 Text 顯示多行字串時,會向左對齊。本節範例的「Text(詩句[索引])」只顯示一行詩句。