利用 UIImageView 實現多張圖片連續播放的動畫

從 iOS 13 開始,我們可以利用 function CGAnimateImageDataWithBlock & CGAnimateImageAtURLWithBlock 播放 gif。

不過 iOS 13 之前的要怎麼辦呢 ? 沒關係,我們可以換個方法,先將 gif 分解成多張圖片,然後透過 UIImageView 實現多張圖片連續播放的動畫效果。

UIImageView 播放動畫的步驟說明。

1 下載 gif

2 將 gif 轉成多張圖片

將 gif 上傳到網站,將 gif 轉成多張圖片後下載。

點選 Download ZIP File。

其它 gif 轉成多張圖片的網站。

3 將圖片加到 Xcode 專案的 Assets.xcassets。

4 在 controller 的 function viewDidLoad 裡設定 image view 播放動畫。

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
let imageView = UIImageView(frame: CGRect(x: 30, y: 30, width: 201, height: 131))
view.addSubview(imageView)
let animatedImage = UIImage.animatedImageNamed("a06fc2aa3f2a4968e4716e36f4a0cb3b-", duration: 1)
imageView.image = animatedImage
}
}

說明

  • 產生 image view。

寬高請參考原始圖片的尺寸。

let imageView = UIImageView(frame: CGRect(x: 30, y: 30, width: 201, height: 131))
  • 產生代表動畫圖片的 UIImage 物件。
let animatedImage = UIImage.animatedImageNamed("a06fc2aa3f2a4968e4716e36f4a0cb3b-", duration: 1)

呼叫 UIImage 的型別 function animatedImageNamed,參數 name 傳入圖片的名字,duration 傳入動畫的時間(以秒為單位)。

等等,我們不是有多張圖片,名字是 a06fc2aa3f2a4968e4716e36f4a0cb3b-0 到 a06fc2aa3f2a4968e4716e36f4a0cb3b-7 嗎 ? 別擔心,我們只需傳入開頭的 a06fc2aa3f2a4968e4716e36f4a0cb3b-,function animatedImageNamed 很聰明,它會自動在結尾補上數字,從數字 0 開始找尋以此數字開頭的圖片,因此它將找到 a06fc2aa3f2a4968e4716e36f4a0cb3b-0 ~ a06fc2aa3f2a4968e4716e36f4a0cb3b-7 組合出圖片的動畫。

關於圖片名字的部分,還有幾個要注意的小地方:

  1. 圖片名字必須以數字結尾,從某個數字開始依序遞增,因為 function animatedImageNamed 將以此決定圖片動畫的順序,比方剛剛範例的圖片從數字 0 開始。
  2. 圖片名字結尾的數字最大可以到 1024,因此我們最多可以用 1025 張圖片組合出動畫。
  • 將 image view 的 image 指定為代表動畫圖片的 UIImage 物件。
imageView.image = animatedImage

輪播照片

利用剛剛的方法,我們還可以實現簡單的輪播照片效果。

以下我們加入 peter 4 張帥氣的照片。

設定 duration 為 8,因為有 4 張圖片,所以每張圖片將停留 2 秒的時間,然後再換下一張圖片。

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.

let imageView = UIImageView(frame: CGRect(x: 30, y: 30, width: 300, height: 300))
imageView.contentMode = .scaleAspectFit
view.addSubview(imageView)
let animatedImage = UIImage.animatedImageNamed("peter", duration: 8)
imageView.image = animatedImage
}

此做法可以做到簡單的照片輪播,不過換圖時是瞬間切換,因此不會有水平移動或淡入淡出的動畫效果。

讓動畫跑固定次數

剛剛的方法可以製作出跑到地老天荒的動畫,但若想讓動畫只跑固定的次數,比方一次就好呢 ?

我們必須改用 animationImages 才能限制動畫的次數,方法如下:

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let imageView = UIImageView(frame: CGRect(x: 30, y: 30, width: 201, height: 131))
view.addSubview(imageView)
var images = [UIImage]()
for i in 0...7 {
images.append(UIImage(named: "a06fc2aa3f2a4968e4716e36f4a0cb3b-\(i)")!)
}
imageView.animationImages = images
imageView.animationDuration = 1
imageView.animationRepeatCount = 1
imageView.image = images.last
imageView.startAnimating()
}

說明:

  • 產生動畫圖片的 array,將它存到 image view 的 animationImages。
var images = [UIImage]()
for i in 0...7 {
images.append(UIImage(named: "a06fc2aa3f2a4968e4716e36f4a0cb3b-\(i)")!)
}
imageView.animationImages = images
  • 指定動畫的時間(animationDuration) 1 秒,動畫的次數(animationRepeatCount)一次。
imageView.animationDuration = 1
imageView.animationRepeatCount = 1
  • 設定 image view 的圖片為動畫的最後一張圖。

讓動畫終止時顯示最後一張圖。如果忘了寫這一次,動畫結束時圖片將無情地消失在我們眼前。

imageView.image = images.last
  • 開始動畫。
imageView.startAnimating()

停止動畫

使用套件 SwiftyGif

我們也可以使用套件播放 gif,比方使用 SwiftyGif

--

--

彼得潘的 iOS App Neverland
彼得潘的 Swift iOS App 開發問題解答集

彼得潘的iOS App程式設計入門,文組生的iOS App程式設計入門講師,彼得潘的 Swift 程式設計入門,App程式設計入門作者,http://apppeterpan.strikingly.com