單字App
倒數第二堂課的課堂實作 ,回家給APP穿新衣並完善其功能 。
先把peter提供的各個單字txt檔丟入專案資料夾中 ,因為缺了X的檔案,所以我自己隨便編寫了一個放進去 。
然後建立三個class檔案分別為 :字母按鈕列表頁的mainViewController 、英文頁面的EnglishViewController跟中文頁面的ChineseViewController 。
拉出三個View Controller頁面:字母按鈕列表頁 、英文頁 、中文頁 ,並在"字母按鈕列表頁"跟"中文頁"前面插入Navigation Controller。
接著將26個字母按鈕拉segue(show)連線到EnglishViewController。
EnglishViewController(英文頁面)右上角的"中文"按鈕 ,拉segue(Present Modally)到中文頁前面的Navigation Controller,並將Transition選為"Flip Horizontal" 製造翻牌的動態效果。
一切就緒後,便可以開始寫程式惹!
首先在mainViewController(字母按鈕列表頁)中 ,寫一個用來傳值的prepare() 。把按鈕上的文字傳到EnglishViewController(英文頁面)作為navigation bar上面的title。
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
let but = sender as! UIButton
let controller = segue.destination as!
EnglishViewController
controller.alphabet = but.currentTitle!
}
EnglishViewController(英文頁面)中,先宣告alphabet 、lineArray 、array、vocabularIndex四個變數。其中vocabularIndex是用來索引陣列中的資料。
var alphabet:String = "" //navigation bar title上顯示的字
var lineArray = [""]
var array = [""]
var vocabularIndex = 0 //第幾筆資料
將單字跟句子的兩個Label拉IBOutlet ,再將"前一筆資料"跟"後一筆資料"的按鈕拉IBAction。
@IBOutlet weak var word: UILabel! //英文單字
@IBOutlet weak var sentenceLabel: UILabel! //英文句子
@IBAction func prevBtn(_ sender: Any) {} //前一筆資料的按鈕
@IBAction func nextBtn(_ sender: Any) {} //後一筆資料的按鈕
在viewDidLoad()中,寫入
self.navigationItem.title = alphabet
let path = Bundle.main.path(forResource: alphabet, ofType: "txt")
let content = try! String(contentsOfFile: path!, encoding:String.Encoding.utf16) //接收路徑跟編碼
array = content.components(separatedBy: "\n")//依斷行切割資料
show()
(1)self.navigationItem.title = alphabet 是讓navigation bar的title顯示為前一頁(mainViewController)傳來的按鈕上的英文字
(2)let path = Bundle.main.path(forResource: alphabet, ofType: “txt”),設定檔案的路徑,由前一頁傳來的alphabet值來決定呼叫哪個txt檔
(3)let content = try! String(contentsOfFile: path!, encoding:String.Encoding.utf16),取得檔案裡的資料
(4)array = content.components(separatedBy: “\n”) ,將txt中的資料用斷行來分隔,並將分隔後的每一行資料放入array陣列中 。由於txt檔中的資料長成下面這樣 :
每行由 英文單詞(空格)中文單詞(空格)英文句子(空格)中文句子 組成,所以用斷行的方式將資料區隔開後,array的長相就會變成:[ 英文單詞(空格)中文單詞(空格)英文句子(空格)中文句子, 英文單詞(空格)中文單詞(空格)英文句子(空格)中文句子, 英文單詞(空格)中文單詞(空格)英文句子(空格)中文句子]
之後再執行show()這個方法
func show(){
let line = array[vocabularIndex]
lineArray = line.components(separatedBy: "\t")//依空白切割資料
let vocabulary = lineArray[0]
let sentence = lineArray[2]
word.text = vocabulary
sentenceLabel.text = sentence
}
(1)一開始宣告var vocabularIndex = 0初始值為0 ,所以let line = array[0],可以取出array陣列中的第一筆資料[英文單詞(空格)中文單詞(空格)英文句子(空格)中文句子],也就是txt檔中的第一行資料 。
(2)接著 lineArray = line.components(separatedBy: “\t”),用空格為依據來分隔資料。剛剛使用let line = array[0]取出了[英文單詞(空格)中文單詞(空格)英文句子(空格)中文句子]這筆資料後,用空格進行分隔後存入lineArray陣列後,就會變成[英文單詞,中文單詞,英文句子,中文句子]。
(3)let vocabulary = lineArray[0] =英文單詞
let sentence = lineArray[2]=英文句子
(4)將vocabulary跟 sentence的值指派給word跟sentenceLabel這兩個label做顯示
然後回頭來處理prevBtn跟nextBtn這兩個按鈕的IBAction
@IBAction func prevBtn(_ sender: Any) {
vocabularIndex -= 1
if vocabularIndex < 0 {
vocabularIndex = array.count-1
//如果已經在第一行了,就秀最後一行
}
show()
}
@IBAction func nextBtn(_ sender: Any) {
vocabularIndex += 1
if vocabularIndex > array.count-1 {
vocabularIndex = 0
//如果已經在第一行了,就秀第一行
}
show()
}
按"前一筆資料"按鈕時,陣列索引值-1(vocabularIndex -= 1),讀取前一筆資料。按"後一筆資料"按鈕時,陣列索引值+1(vocabularIndex+= 1),讀取後一筆資料。
如果目前畫面中讀取的是第一行資料array[0],按下"前一筆資料"的按鈕,就秀出txt檔中的最後一筆資料。
如何得知txt檔中有幾行,可以使用array.count這個方法來得知陣列中的元素數。例如array[]中有100筆資料,array.count就會=100,那要讀出最後一筆資料的寫法就是array[99]。因此當array[0],0-1<0, 就執行vocabularIndex = array.count-1來讀取最後一筆資料。
換言之當畫面中已經秀出最後一筆資料時,按了後一筆資料的按鈕,就將vocabularIndex值歸0,秀出第一筆資料。
再使用prepare(),將資料傳到下一頁(ChineseViewController)。因為EnglishViewController跟ChineseViewController中間夾了一個Navigation Controller,所以需要轉手一下。然後再將linearray陣列[英文單詞,中文單詞,英文句子,中文句子]中的lineArray[1]=中文單詞跟lineArray[3]=中文句子,還有用於顯示navigation title的alphabet值傳到ChineseViewController。
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
let navController = segue.destination as! UINavigationController
let chiController = navController.topViewController as! ChineseViewController
chiController.vocabulary = lineArray[1]
chiController.sentence = lineArray[3]
chiController.alphabet = alphabet
}
ChineseViewController中,先宣告vocabulary 、sentence、alphabet三個變數來接值。然後將顯示"中文單詞"跟"中文句子"的label拉IBOutlet連線。
再從navigation bar上的"英文"按鈕拉IBAction,使用" self.dismiss(animated: true, completion:nil)"的方法返回英文頁。
@IBAction func showEnglish(_ sender: Any) {
self.dismiss(animated: true, completion:nil)
}
viewDidLoad()中,處理一下接值與顯示,就終於告一段落惹!
word.text = vocabulary
sentenceLabel.text = sentence
self.navigationItem.title = alphabet
這個月,姊姊從加拿大帶小外甥回台探親 ,下了班就只想跟寶包玩 ,把swift丟一邊!! 小寶包真得好可愛,不能只有我看到 。