#Note - 製作 Line App 首頁的 Navigation Bar 動畫顯示效果

打開 Line App 首頁,將畫面往上滑,滑到自己的名字跟照片看不到的時候,會發現左上角的地方會浮現出小小的照片跟名字;將畫面再往下滑,個人資料又出現的時候左上角原先浮現的照片跟名字就又消失了!如下面圖片:

這次來筆記實作出這個動畫效果的方法!

前情提要:已經用 Table View Controller 做出基本畫面

那我們就開始!

⭐️ Navigation Bar 客製化

先來說說 Navigation Bar 上的按鈕、文字跟圖片怎麼來的🤔

這一條是 Navigation Bar,我們可以從 Library 加入 Bar Button Item 到 Navigation Bar 進行客製化

例如我們用一個新的 View Controller 連結 Navigation Controller 後,在 Bar 上加入一個 Bar Button Item,加入之後左方的目錄會產生 Left Bar Button Items 跟 Right Bar Button Items,我們可以從屬性面板去客製化 Item 的文字、圖片、顏色、大小等等

我們加入 4 個 Bar Button Item 進去,接著從 Library 拖曳一個 View 到 Navigation Bar 上。沒錯!就是 View!他也可以被加進去,所以我們可以再把 Image View 跟 Label 放到 View 裡面,做出我們要的樣子!

他們全部都在 Right Bar,這樣調整 View 的寬度的時候才會影響其他按鈕的排列間距(如最右圖)

做完的目錄跟畫面長這樣:

因為後面判斷邏輯會用到 View 的 Alpha 值,我們先將 Alpha 設為非 1 的任意值

⭐️ 程式部分

照片跟名字都裝在 View 裡,所以我們只要針對 View 去設定動畫就好啦!

  • 先幫 View 拉 outlet
class mainTableViewController: UITableViewController {

@IBOutlet weak var nameView: UIView!
}
  • 讓 View 在一開始畫面顯示的時候先隱藏
override func viewDidLoad() {
super.viewDidLoad()
nameView.isHidden = true
}
  • View 什麼時候該出現跟消失,是以 Scroll View 離原本位置捲動的 y 距離來判斷,而 Table View Controller 本來就內建 Scroll View 的相關功能跟方法,所以可以直接使用 Scroll View 的 method
  • 因為動畫的執行時間會是在捲動 Scroll View 的時候,所以採用scrollViewDidScroll(_:) 方法!
override func scrollViewDidScroll(_ scrollView: UIScrollView) {

//讓View出現
//當Scroll View的y偏移值大於130,且View的透明度不為1時,執行動畫
if scrollView.contentOffset.y >= 130 && nameView.alpha != 1{
nameView.isHidden = false //讓View顯示

nameView.alpha = 0 //執行動畫前View的Alpha起始值為0
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.3, delay: 0, animations: {
self.nameView.alpha = 1 //執行動畫後Alpha值變為1
})

//讓View消失
//當Scroll View的y偏移值小於130,且View的透明度已為1時,執行動畫
}else if scrollView.contentOffset.y < 130 && nameView.alpha == 1{
nameView.alpha = 1 //執行動畫前View的Alpha起始值為1
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.3, delay: 0, animations: {
self.nameView.alpha = 0 //執行動畫後Alpha值變為0
})
}
}

說明:

  • contentOffset.y 是 Scroll View 捲動後離原始位置所偏移的 y 距離,當距離超過 130 時,讓 View 顯示
if scrollView.contentOffset.y >= 130 && nameView.alpha != 1{
nameView.isHidden = false
  • 如果只用 contentOffset.y ≥ 130 一個條件去判斷的話,只要捲動時 Scroll View 的 contentOffset.y 大於 130,動畫就會不停重複執行,如下圖

但是我們希望它出現後繼續捲動畫面時不會消失,所以需要多一個判斷條件:當 View 的 Alpha 值不等於 1 的時候,才執行動畫
這也是我們一開始先將 Alpha 值改為非 1 的任意值的原因

nameView.alpha = 0
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.3, delay: 0, animations: {
self.nameView.alpha = 1
})
  • 我們使用 UIViewPropertyAnimator 的 runningPropertyAnimator 方法設定參數來執行動畫,動畫開始到結束時間為 0.3 秒

動畫執行前後影響的是 View 的 Alpha 值,我們需要在呼叫 runningPropertyAnimator 前給予初始值(0),在呼叫時給予目標值(1),讓 View 在 0.3 秒的時間從透明變成不透明,產生慢慢浮現出的動畫效果!

現在看起來是我們要的,View 浮現後繼續滾動會維持顯示狀態不會重複執行動畫了!

  • 當 Scroll View 快要回到原始位置,個人資料顯示在畫面上的時候,View就要消失,程式的部分同理!
if scrollView.contentOffset.y >= 130 && nameView.alpha != 1{
nameView.isHidden = false
nameView.alpha = 0
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.3, delay: 0, animations: {
self.nameView.alpha = 1
})
}else if scrollView.contentOffset.y < 130 && nameView.alpha == 1{
nameView.alpha = 1
UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 0.3, delay: 0, animations: {
self.nameView.alpha = 0
})
}

這次呼叫 runningPropertyAnimator 前給予初始值(1),在呼叫時給予目標值(0),讓 View 在 0.3 秒的時間從不透明變成透明,產生慢慢消失的動畫效果!

完成!!👏

附上 GitHub 連結

--

--