iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0
Mobile Development

用 SwiftUI 魔法變出 Leetcode 刷題知識學習 App!系列 第 11

Day 11: LeetCode題目詳情頁面,使用 SwiftUI Group 和 AttributedString

  • 分享至 

  • xImage
  •  

延續昨天製作的 LeetCode 題目詳細頁面,如果你還沒看,可以前往 LeetCode題目詳情頁面,使用 SwiftUI Text 和 ScrollView 先把前面的教學學習過一遍再來接續今天的內容,會比較進入狀況。

針對上一篇分析,我們已經成功加入題目以及描述,這次我們要繼續在 VStack 繼續增補內容如下:

  • 範例說明,提供 Input 會有的資料型態與資料內容,還有 Output 預期結果
  • 顯示提示,讓攥寫程式碼的人知道邊界條件在哪邊,好掌握測試案例
  • 相關標籤,顯示題目屬於哪個演算法或是資料結構主題

VStack 加入範例說明

而我們一股腦往下增加範例說明的 Text 文字,程式碼如下。

Text("**Example 1:**").font(.title2)
Spacer().frame(height: 15)
Text("""
**Input:** nums = [2,7,11,15], target = 9
**Output:** [0,1]
**Explanation:** Because nums[0] + nums[1] == 9, we return [0, 1].
""").foregroundColor(.gray)
Spacer().frame(height: 10)
Text("**Example 2:**").font(.title2)
Spacer().frame(height: 15)
Text("""
**Input:** nums = [3,2,4], target = 6
**Output:** [1,2]
""").foregroundColor(.gray)
Spacer().frame(height: 10)

就會發現 Xcode 狠狠地報錯了,不讓我們編譯程式碼,那是因為 VStack 最多只能放 10 個 View,不能再多了

錯誤訊息為:
Extra arguments at positions #11, #12 in call

Group{
       Text("**Example 1:**").font(.title2)
       Spacer().frame(height: 15)
       Text("""
       **Input:** nums = [2,7,11,15], target = 9
       **Output:** [0,1]
       **Explanation:** Because nums[0] + nums[1] == 9, we return [0, 1].
       """).foregroundColor(.gray)
       Spacer().frame(height: 10)
       Text("**Example 2:**").font(.title2)
       Spacer().frame(height: 15)
       Text("""
       **Input:** nums = [3,2,4], target = 6
       **Output:** [1,2]
       """).foregroundColor(.gray)
       Spacer().frame(height: 10)
 }

解決方式則是多包一層 Group,讓他覺得這一堆元件都屬於一個 Group 的 View。

此時我們成功把這題的範例資料都顯示出來給刷題者觀看。

VStack 加入提示邊際條件

LeetCode 題目都會定義一個輸入值的最大最小條件,或是輸出最大最小的條件,好讓程式端能夠掌握邊際條件,不至於讓程式時間或是空間爆掉。

因為提供這些條件都是條列式呈現,所以前面都會有個小圓黑點,雖然 Text 支援基本的 Markdown ,但是小圓黑點的語法竟然不支持,所以我們只好用編碼去呈現。

Spacer().frame(height: 40)
Group{
      Text("**Constraints:**").font(.title2)
      Spacer().frame(height: 10)
      Text("""
      \u{2022}  2 <= nums.length <= 10^4
      \u{2022}  -10^9 <= nums[i] <= 10^9
      \u{2022}  -10^9 <= target <= 10^9
      """).foregroundColor(.gray)

}

此時一個超完整的 LeetCode 題目說明大致上完成了,也就是說看到這個題目,就可以開始消化並思考要怎麼樣寫程式碼。

但是我們想要更標註幾個關鍵字,但是因為 Markdown 的語法 SwiftUI Text 吃不到,於是 AttributedString是一個很好的處理方式,參考此網站的教學:在 SwiftUI 使用 Markdown 輕鬆格式化文本

var attributedString: AttributedString = {
        do {
            var text = try AttributedString(markdown: """
            Given an array of integers `nums` and an integer `target`, return indices of the two numbers such that they add up to `target`.
            
            You may assume that each input would have **exactly one solution**, and you may not use the same element twice.
            
            You can return the answer in any order.
            """)

            if let range = text.range(of: "nums") {
                text[range].backgroundColor = Color("ColorGray")
                text[range].foregroundColor = .black
            }

            if let range = text.range(of: "target") {
                text[range].backgroundColor = Color("ColorGray")
                text[range].foregroundColor = .black
            }

            return text

        } catch {
            return ""
        }
    }()

我們成功標註了 nums 跟 target 給予灰底上色,但是我們要自定義的灰色,這時候就會利用 Assets 專門放資源檔的地方去建立 Color Set。

  1. 點擊 Assets
  2. 按 + 符號展開的列表裡面選 Color Set
  3. 點選顏色方塊
  4. 編輯顏色名字,這裡叫做 ColorGray
  5. 在色盤裡選擇你訂製的灰色

這就是我們在呼叫自己訂製顏色時的方法,直接用我們設定的 Color Name。

Color("ColorGray")

我們訂製的灰色底就出現了,這樣讓我們的題目描述更加的具有強調性。

總結

我們學會了利用 SwiftUI 讓 LeetCode 題目文本呈現更加的豐富,這一路走來確實不容易,因為要補充很多 SwiftUI 的知識,接下來我們要開始逐步帶 LeetCode 演算法知識,讓這個 App 能夠更加具有學習力道。


上一篇
Day 10: LeetCode 題目詳情頁面,使用 SwiftUI Text 和 ScrollView
下一篇
Day 12: 導讀 LeetCode 知識 - 陣列與字串(Swift)
系列文
用 SwiftUI 魔法變出 Leetcode 刷題知識學習 App!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言