今年最受歡迎的電影
從TMDB搜尋Top 20電影排行
前陣子研究了TMDB,最近則是來實際應用看看,目前完成了以下功能:
- 從TMDB載入2019年度前20部最受歡迎電影排行榜。
- 電影海報下拉放大圖片效果。
- 首頁電影推薦,從Top 20電影裡面顯示電影海報,每秒換一張圖片。
- 使用TableViewCell列出前20部最受歡迎電影,顯示電影名稱及海報、發行日期、電影評分。
成果
最近推出iphone 11剛好也可以更新xcode來用模擬器試用看看,沒看到 iphone 11 pro背後的三顆鏡頭的話,兩支手機正面外觀除了大小不同,看起來好像沒什麼差別;iphone 11 pro我個人蠻喜歡夜幕綠的,改天再去店面看看實機試用一下。
實作紀錄
一、App畫面
首頁畫面命名為FirstMovieViewController ,加入 image view,再用container view 連結搭配 static cell 的 table view controller。
設定畫面的類別,放imageView的FirstMovieViewController 繼承 UIViewController,放電影Top 20清單 TableView的SecondMovieTableViewController 繼承 UITableViewController。
二、從TMDB 載入2019年度前20部最受歡迎電影排行資料
TMDB的API URL我是從這裡去設定搜尋條件,依受歡迎度做排序(Sort by popularity)、主要發布日期(primary_release_year:2019),設定完按send request會給我一個URL。
新增Swift File建立自訂型別,針對需要的資料做解析即可,於是我自訂了電影名稱(title)、評分(vote_average)、發布日期(release_date)、電影海報(poster_path),因為怕自己會搞混所以我名稱幾乎都跟API的名稱一樣。
寫function用URLSession連結取得電影海報的資料,透過URLSession的dataTask執行抓資料,並在背景儲存資料array,最後呼叫resume才會開始執行任務。
接著在imageView裡顯示電影海報。
問題?
一開始抓不到電影海報的資料,圖片都無法顯示,很困惑為何資料都抓到了,image view裡面還是一片空白。
仔細讀API文件後才發現,TMDB API裡圖片的取得有些限制,必須先指定欲取得的圖片尺寸,才能夠取得圖片資料。
到底要怎麼先指定size再取得海報圖片的URL了,一開始也是不知道該怎麼辦,然後就先擱在一邊環島去了(笑),環島第一天在抵達高雄後,因為時間是正中午天氣很炎熱不想在外面曬太陽,找了一間咖啡廳坐下,打開MacBook Air又開始想~要怎麼寫呢?
不知道是不是因為腦袋有放鬆再開始動腦的關係,靈光一閃想到,如果我已經取得海報poster_path的URL的話,在poster_path的URL前再加上指定的海報Size不就好了嗎?
尺寸API URL + 海報URL
假設海報poster_path的URL為:ziEuG1essDuWuC5lpWUaw1uXY2O.jpg
尺寸的URL為:https://image.tmdb.org/t/p/w500/
合起來就好了!
https://image.tmdb.org/t/p/w500/ziEuG1essDuWuC5lpWUaw1uXY2O.jpg
其實沒有很難不用想太多(笑),於是我這樣寫:
let moviesImage = "https://image.tmdb.org/t/p/w500/" + moviesData.results[self.index].poster_path!
海報圖片終於顯示出來了!
還是說旅行也能當作充電讓腦袋清晰一點呢(笑~)
三、電影海報下拉放大圖片效果
FirstMovieViewController裡面加入的 image view就是要來放電影海報的,storyboard拉好之後設定 image view的auto layout,高度條件設為 450,之後往下捲動時,將修改高度的條件,增加圖片的高度。
連結圖片高度條件的 outlet — imageViewHeightConstraint
class FirstMovieViewController: UIViewController {@IBOutlet var TopMoiveImageView: UIImageView!@IBOutlet weak var imageViewHeightConstraint: NSLayoutConstraint!//連結圖片高度條件的 outlet imageViewHeightConstraintvar SecondMovieTableController:SecondMovieTableViewController?
}
設定表格的 contentInset 及背景顏色 — 設定於表格的上方顯示圖片,圖片的高度設定為 450,因此定義常數 imageOriginalHeight 儲存高度 450,然後將表格 contentInset 的 top inset 設為 imageOriginalHeight,讓表格的上方多出一塊高度 450 points 的空間。
class SecondMovieTableViewController: UITableViewController {//設定表格的 contentInse,讓表格的上方多出一塊高度 450 points 的空間let imageOriginalHeight: CGFloat = 450override func viewDidLoad() {super.viewDidLoad()tableView.contentInset = UIEdgeInsets(top: imageOriginalHeight, left: 0, bottom: 0, right: 0)}
捲動時調整圖片的高度和亮度 — 定義 protocol UIScrollViewDelegate 的 scrollViewDidScroll(_:),此 function 將在表格捲動時觸發,並在其中調整圖片的高度和亮度。
從起始位置往下捲動時 scrollView.contentOffset.y 將小於 originalOffsetY,修改圖片的高度條件,依據捲動的距離變高,而從起始位置往上捲動時將設定表格的背景顏色,讓圖片隨著捲動的距離逐漸變暗。
四、從Top 20電影裡面顯示電影海報,每秒換一張圖片
前面設定好圖片位置及下拉放大、向上捲動變暗的功能後,就要來寫每秒換一張圖片的效果了。
本來想要依照排行榜一張一張去換圖片,想不到要怎麼寫,先用亂數產生圖片的方法試試看。
畫面載入後使用timer去執行每秒鐘換一次海報圖片,順序亂數決定。
var timer:Timer?
override func viewDidLoad() {super.viewDidLoad()time()//畫面載入後即執行每秒換一張電影海報}//每秒換一張電影海報func time(){timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true){(timer) in self.newImage()
//呼叫亂數function}}//亂數換海報func newImage(){index = Int.random(in: 0...20)getMoiveInfo()
//呼叫取得電影資料的function}
問題?
用模擬器Run一陣子之後app突然閃退,顯示『 Index out of range 』,看來我的亂數方法不是個好方法(汗…)。
請教小王子之後才知道我每執行亂數一次就重新載一次資料不太好,後來想想還是要依照排行榜一張一張去換圖片比較適當,小王子提供我比較好的方法:改成從TMDB載下來的資料先存成array,再從背景執行,確認movies.count是否大於零,如果為true,則執行self.setMovieInfo(film:self.movies[self.index])設定電影海報圖片及執行self.time()改成每三秒換一次海報圖片。
當然圖片的URL也要注意,要遵從API的規定,先指定尺寸再取的圖片URL。
if let imageAddress = film.poster_path{if let imageURL = URL(string: "https://image.tmdb.org/t/p/w500/" + imageAddress)
載資料失敗會出現提示訊息。
每三秒換下一張電影海報。
原本是設定畫面載入就執行timer一次重新載電影資料,現在改成畫面一載入就執行getMoiveInfo載好電影資料,再依照count去決定海報圖片,執行每三秒換海報圖片的動作,比較不耗資源。
override func viewDidLoad() {super.viewDidLoad()getMoiveInfo()}
也要設定關閉app畫面即停止timer,以防止在背景持續執行。
//關閉app畫面即停止timer,以防止在背景持續執行override func viewDidDisappear(_ animated: Bool) {timer?.invalidate()}
五、列出前20部最受歡迎電影,顯示電影名稱及海報、發行日期、電影評分
在SecondMovieTableViewController裡先抓電影資料,並把資料存成array。
以Table View Cell顯示20部最受歡迎的電影名稱、海報、發行日期及電影評分。
繼續下個功能,未完待續…
續集(關於預告片URL的研究):
前言(研究TMDB API):
GitHub
歡迎一起腦力激盪:)
參考文章:
如果有值得大家參考的地方再麻煩大家幫我拍拍手喲,謝謝大家耐心閱讀🙇♀️