看完上一篇介紹,我們學習到 Two pointers 是 LeetCode 解題的重要關鍵,如果學會了,很多題目都可以迎刃而解,而我們今天要利用 SwiftUI 動畫效果去呈現這個概念的圖像效果,就讓我們開始學習吧!
參考如下程式碼說明,這個是專屬 function 調用動畫時使用。
withAnimation(.easeInOut(duration: 1)) {
// 其他程式碼內容
}
如果我們要在 SwiftUI 上面呈現動畫則會使用到 withAnimation
這個方法,而這個方法 easeInOut
會讓動畫逐漸依據秒數一秒緩慢淡出。
這個動畫方法會與綁定參數一起交互進行,在 LeetCode 922 題裡面我們使用到 Two pointers 的兩個參數如下:
@State private var evenIndex = 0
@State private var oddIndex = 1
而當我們 Two pointers 走訪的時候,會替我們陣列顯示的數字方框上邊線顏色,代表我們的指針。
Text("\(nums[index])")
.padding(8)
.background(Color.green)
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.purple, lineWidth: 2)
)
針對偶數指針上色紫色邊線,利用 RoundedRectangle
設定,而奇數則會是紅色。
原始陣列因為會變動仍然會使用 State 更新,會顯示成這樣。
@State private var nums = [4, 2, 5, 7]
多個 UI 元件動態生成的時候,會用 ForEach
去拿陣列的索引去對應產生。
HStack(spacing: 20) {
ForEach(nums.indices, id: \.self) { index in
if index == evenIndex {
Text("\(nums[index])")
.padding(8)
.background(Color.green)
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.purple, lineWidth: 2)
)
} else if index == oddIndex {
Text("\(nums[index])")
.padding(8)
.background(Color.green)
.cornerRadius(8)
.overlay(
RoundedRectangle(cornerRadius: 8)
.stroke(Color.red, lineWidth: 2)
)
} else {
Text("\(nums[index])")
.padding(8)
.background(Color.green)
.cornerRadius(8)
}
}
}
在 iOS 模擬器的畫面如圖
按了 Apply Operation 按鈕後開始跑動畫,最後結果如下。
走訪的程式碼邏輯如下,就是我們昨天寫的題目,只是加上動畫。
func applyOperationWithAnimation() {
while evenIndex < nums.count && oddIndex < nums.count {
withAnimation(.easeInOut(duration: 1)) {
if nums[evenIndex] % 2 == 0 {
evenIndex += 2
} else {
if nums[oddIndex] % 2 != 0 {
oddIndex += 2
} else {
let temp = nums[evenIndex]
nums[evenIndex] = nums[oddIndex]
nums[oddIndex] = temp
}
}
}
}
}
而我們的按鈕就是負責點擊後執行此動畫邏輯。
Button("Apply Operation") {
applyOperationWithAnimation()
}
因為雙指針的關係我們學習到如何使用動畫效果來呈現走訪的狀態,更容易理解這個題目的程式運作,也凸顯出 SwiftUI 在撰寫動畫上其實十分簡單,只要設定幾個參數就能達到我們想要的效果。