通過一些簡單的動畫,可以讓圖片在切換的過程變得有趣許多。
在 ViewController 的正中央放置一個 UIImageView 用來顯示準備好的6張圖片。
目標:
自定義一個繼承於 UIImageView 的 ImageSliderView 在這個 class 中實現切換圖片的動畫。
func setImage(_ newImage:UIImage, animated: Bool) {
if animated {
let animation = CABasicAnimation(keyPath: "contents")
animation.fromValue = image?.cgImage
animation.toValue = newImage.cgImage
animation.duration = defaultDuration
layer.contents = image?.cgImage
layer.add(animation, forKey: nil)
}
image = newImage
}
在畫面中央放置 ImageSliderView 並且啟動 timer 每 1.5秒執行一次切換圖片的動畫
private func setupView() {
// setup imageSliderView
let screen = UIScreen.main.bounds
let image = images[0]
let imageWidth = screen.width - 20
let imageHeight = ((screen.width - 20) / image.size.width) * image.size.height
imageSliderView = ImageSliderView(frame: CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight))
imageSliderView.center = CGPoint(x: view.bounds.width / 2, y: view.bounds.height / 2)
imageSliderView.layer.borderWidth = 3
imageSliderView.layer.borderColor = UIColor.black.cgColor
imageSliderView.setImage(image, animated: false)
view.addSubview(imageSliderView)
// setup timer
timer = Timer.scheduledTimer(timeInterval: 1.5, target: self, selector: #selector(HomeViewController.changeImageEvent), userInfo: nil, repeats: true)
}
通過取餘數的方法讓 nextPos 處於 0~5之間,取完圖片再讓 currentPos 前進一位。
圖片切換的動畫依舊是通過 UiView.animate 方法,改變最終 imageSliderView 的 bounds 系統就會幫將過程變成動畫。
要記得重新設定一次 center 讓圖片維持在畫面正中央。
@objc func changeImageEvent() {
// take next image
let nextPos = currentPos % images.count
currentPos += 1
imageSliderView.setImage(images[nextPos], animated: true)
// image changing animation
let screen = UIScreen.main.bounds
UIView.animate(withDuration: 0.5, animations: {
// calculate new iamge bounds
let imageWidth = screen.width - 20
let imageHeight = ((screen.width - 20) / self.imageSliderView.image!.size.width) * self.imageSliderView.image!.size.height
var tempRect = self.imageSliderView.bounds
tempRect.size = CGSize(width: imageWidth, height: imageHeight)
// update imageSliderView's bounds & center
self.imageSliderView.bounds = tempRect
self.imageSliderView.center = CGPoint(x: self.view.bounds.width / 2, y: self.view.bounds.height / 2)
})
}