簡要

搜尋這頁部分
在下面的CollectionView有做特效
所有圖片在固定時間都會換圖片
今天就試著來效仿原生 Uber eat

圖片幻燈片

看到這個效果第一時間
應該後想到UIImage幻燈片
把一組圖片Array塞到image
並且設定duration 切換時間
圖片的模式先給他自動照比例縮放
contentMode = scaleAspectFit
來看一下程式碼

let imageView = UIImageView()
imageView.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
imageView.backgroundColor = UIColor.black
let images = [UIImage(named: "food1"),
              UIImage(named: "food2"),
              UIImage(named: "food3"),
              UIImage(named: "food4"),
              UIImage(named: "food5"),
              UIImage(named: "food6")]
let animatedImage = UIImage.animatedImage(with: images as! [UIImage], duration: 3)
imageView.image = animatedImage
imageView.contentMode = .scaleAspectFit

Demo

但好像有點不對

自細看一下原生APP實作的效果
其實在轉換的時候
有做兩個圖片交疊
淡入淡出的效果
如果使用幻燈片的話沒有
會直接換過去
試試看animate

animate

之前在開發時
如果資料未從API回傳時
往往都會先把物件設定為alpha = 0.0先讓他透明
等待回傳成功後
設定
duration動畫時間
並且讓他
alpha = 0.1就會有淡入`的效果

sender.alpha = 0.0
UIView.animate(withDuration: 1.5, animations: {
    sender.alpha = 1.0
   }, completion:{(finished) in
        sender.alpha = 1.0
})

Demo

好像有點像
把圖片放進去
使用tag做不同image name
來試試看效果

@IBAction func buttonClicked(sender: UIButton) {
    let buttonTag = sender.tag
    sender.tag = sender.tag + 1
    UIView.animate(withDuration: 0.5, animations: {
        sender.alpha = 0.5
    }, completion:{(finished) in
        sender.alpha = 1.0
        sender.setImage(UIImage(named: "food" + String(buttonTag)), for: .normal)
    })
}

Demo

感覺還是完全不同
雖然有淡入淡出感
但是圖片與圖片之間沒有重疊感
有點失敗
試試看使用兩個imageView做效果
imageViewA負責底層
imageViewB負責上方淡入換照片效果
動畫執行完畢以後 imageViewA = imageViewB
將改變後的圖片交給imageViewA
這裡多設定了masksToBounds
把超出範圍的圖片全部遮罩起來

新增物件

imageViewA.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.width)
imageViewA.contentMode = .scaleAspectFill
imageViewA.layer.masksToBounds = true
self.view.addSubview(imageViewA)

imageViewB.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.width)
imageViewB.contentMode = .scaleAspectFill
imageViewB.layer.masksToBounds = true
self.view.addSubview(imageViewB)

點擊切換圖片

@IBAction func buttonClicked(sender: UIButton) {
    let buttonTag = sender.tag
    sender.tag = sender.tag + 1
    imageViewB.image = UIImage.init(named: "food" + String(buttonTag))
    imageViewB.alpha = 0.0
    UIView.animate(withDuration: 0.5, animations: {
        self.imageViewB.alpha = 1.0
    }, completion:{(finished) in
        self.imageViewB.alpha = 0.0
        self.imageViewA.image = self.imageViewB.image
    })
}

Demo

圖片切換部分差不多
接下來只剩下上方顏色遮罩
以及前方的文字Label
現在來簡單加入
來看看效果如何

物件新增

maskView = UIView()
maskView.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.width)
maskView.backgroundColor = UIColor.init(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.5)
self.view.addSubview(maskView)

titleLabel = UILabel()
titleLabel.frame = CGRect.init(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.width)
titleLabel.textColor = UIColor.white
titleLabel.textAlignment = .center
titleLabel.font = UIFont(name: "Arial", size: 50)
self.view.addSubview(titleLabel)

點擊事件

@IBAction func buttonClicked(sender: UIButton) {
    let buttonTag = sender.tag
    sender.tag = sender.tag + 1
    titleLabel.text = "food" + String(buttonTag)
    imageViewB.image = UIImage.init(named: "food" + String(buttonTag))
    imageViewB.alpha = 0.0
    UIView.animate(withDuration: 0.5, animations: {
        self.imageViewB.alpha = 1.0
    }, completion:{(finished) in
        self.imageViewB.alpha = 0.0
        self.imageViewA.image = self.imageViewB.image
    })
}

Demo

完成 我好像有看到另一種解法
明天一起介紹


Categorized in: