reloadData()
要放在哪個scopeCodingKey 改JSON屬性名
到最頂最底不能滑:
tableView.bounces = false
省略前三個字:
dropFirst(_:)
買進、賣出、買賣超:超過3位數用逗號分開
UILabel 換行
reloadData()
要放在哪個scope
我在part1中提到,做這個練習,最困擾我的是:一樣的程式碼,每次build出來的app,都不一樣。後來我發現了,癥結點就是我把tableView.reloadData()
放在viewDidload
裡。由於不確定下載資訊要多少時間,所以也無法確定在viewDidload
中,下載完成了沒,在viewDidload
中tableView.reloadData(),
很可能根本沒有資料可以reload。造成我之前的慘痛經驗 — 有一次成功build的經驗(想必那次的下載速度特別快),但再也成功不了,甚至開始懷疑起電腦與網速。
最保險的做法,就是把放在確定資訊下載完畢後的地方,也就是URLSession.dataTask(with: url) { (Data?, Response?, Error?)}
當中closure處理Data?的部分。這個closure是在.resume()
執行完畢(也就是資料下載完成後,會才會執行的程式碼。
要注意的是,URLSession預設是在background queue作業,記得要把reloadData放到main queue,因為這是在處理畫面。
CodingKey 改JSON屬性名
上櫃買賣超JSON原始的屬性名第一個字是大寫,而在swift約定成俗的習慣用法,第一個字是大寫的只有型別。因此我們最好能把屬性的名字改成第一個字小寫。如果直接改的話,會出現錯誤,因為要讓swift成功拆解JSON的第一要件就是屬性名要跟JSON的一模一樣(大小寫也要一樣),所以需要經過特別的處理才能「改名」。
這個特別的處理是:
在模擬資料的struct裡,做一個名字叫CodingKeys的enum。
enum CodingKeys: String, CodingKey{
case 新名 = “舊名”
case 新名 = “舊名”
case 新名 = “舊名”
case 舊名
}
*enum的名稱一定要叫CodingKeys(記得加s),enum的 raw value設為String,並遵從protocol CodingKey
(型別沒有s)。
*case 要把所有的屬性寫出來,就算沒有要改名也要寫。沒改名的情形直接寫case 舊名
即可,後面不用等於。
其實就是先用enum完成改名程序,然後下面就直接用新名來指定哪個屬性是什麼型別。把extension寫在上面是為了要容易理解。
而在下載完資料之後,呼叫各屬性的方法跟原本一樣,直接用新名字即可。
到最頂最底不能滑:tableView.bounces = false
這是在設定滑到最頂端與最底端,沒有資料時,能否繼續滑的選項。
而當 tableView.bounces = true
的狀況下,會有兩個選項自動伴隨而來。
tableView.alwaysBounceVertical = false
tableView.alwaysBounceHorizontal = false
省略前三個字: dropFirst(_:)
“Date”: “1100714”
日期我只想要顯示後面四個數字,所以我把前三個字丟掉。我使用了instance method叫dropFirst(_:),
它會return SubString。
但使用後才發現,原來無法把SubString 指派給只接受String的Label.text。
所以後來就把String加在前面,把return 的SubString變成String。
我成功把日期從1100716變成0716了!
買進、賣出、買賣超:超過3位數用逗號分開
我參考這些文章:Swift: Add separator on Integer using NumberFormatter
…………………..利用 NumberFormatter 顯示 Money
…………………..NumberFormatter
…………………..groupingSeparator
…………………..NumberFormatter.Style
做法是分別在Formmater 和 Int 寫extension。再在呼叫買進、賣出、買賣超這三個String資料時,把它們轉為String,後使用設定好的formmater。
NumberFormatter
的作用是將數字變成特定的字串格式。
A formatter that converts between numeric values and their textual representations.
他有一個屬性叫 .groupingSeparator
可指定要用什麼當分隔的東西,我設定逗號。另外一個屬性 .numberStyle
則是一組enum內有apple幫我們內建好的各種格式。我們使用的是.decimal
,就是每三位數加都點分開的格式。
在Int中寫extension,讓這個computed property可以回傳被我們在Formatter改好的格式。
接下來就可以使用啦!請看第42–44行。
成果是:
UILabel 換行
參考文章有:
//12 研究 label 的欄位: Line Breaks & Autoshrink
目前看到比較長的個股名稱,它不足顯示的字就沒有被顯示出來。
91APP 的全名為91APP*-KY。 譜瑞- 的全名為 譜瑞-KY。
奇怪的是,我設定好自動換行了,而當Label放不下時,它卻沒有自動換行。
Lines 0 ,代表沒有限制行數。Line Break:Character Wrap則是完全不省略文字的模式。這是目前剩下的問題。