利用 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 組合出圖片的動畫。
關於圖片名字的部分,還有幾個要注意的小地方:
- 圖片名字必須以數字結尾,從某個數字開始依序遞增,因為 function animatedImageNamed 將以此決定圖片動畫的順序,比方剛剛範例的圖片從數字 0 開始。
- 圖片名字結尾的數字最大可以到 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