「問世間 情是何物」-擇偶APP練習

前言

在元好問的詞「摸魚兒 雁丘辭」裡有句是這麼說著,「問世間 情是何物」,道盡世間男男女女在追尋那份真情時,那種酸酸甜甜的感觸。

若有款app,遇到你心動的另一半時,輸入星座及性別後,就會告訴你是不適合你?!想當然爾,若能這樣子的話,就不會有那些轟轟烈烈的情史及名著了,哈。

我們可以在這個app學到什麼?

  1. 如何使用UIPickerView來輸入資料。
  2. 使用UITextField、UISegmentedControl等資料輸入元件時,其防呆機制要怎麼處理?
  3. 如何抓物件在陣列的位置。
  4. 如何利用Timer來設定排程自動完成程式初始的輸入狀態。
  5. 如何使用UIAlertController來做對話框視窗提醒使用者。
  6. 如何使用arc4random_uniform產生亂數。

先來看app完整的操作畫面

致謝鴨鴨學姐提供的範例及圖片 The One App

先說明這款app的程式邏輯:

  1. 程式開啟時,在背景會以arc4random_uniform產生1個名為randomNum的常數。
  2. 當使用者透過選單來選擇星座以及點選性別後,按下送出鍵。
  3. 程式會先判斷星座值及性別值是否有資料:
    有-取得星座在陣列的位置,再與randomNum比對。
    沒有-用UIAlertController做對話框視窗提醒使用者尚未選填資料。
  4. 比對結果:
    相同-把名為yesImgView的UIImageView設定不隱藏,並把名為noImgView的UIImageView設定隱藏
    不相同-把名為yesImgView的UIImageView設定隱藏,並把名為noImgView的UIImageView設定不隱藏
  5. 上列邏輯跑完後,會立即啟動Timer,設定5秒後做下列的事情:
    (1) 星座的UITextField資料清空。
    (2) 性別的UISegmentedControl狀態設為未選取。
    (3) yesImgView及noImgView設為隱藏。

(拍手!)好,就讓我們開始來寫程式囉!!

程式說明

1. 程式開啟時,在背景會以arc4random_uniform產生1個名為randomNum的常數。

arc4random_uniform(upper_bound)

upper_bound: 為UInt32型態的參數,表示從0開始抓的數量個數,換句話說,該函數生成的隨機數範圍是[0, upper_bound),例如:
arc4random_uniform(12),表示從0開始抓12個數字,也就是從0~11這12個數字裡隨機取1個值回傳。

2. 當使用者透過選單來選擇星座以及點選性別後,按下送出鍵。
我們先宣告一個名為starLists的String陣列,並放進12星座的名稱及日期區間。

接下來就要開始處理UIPickerView了。

Apple Development / UIPickerView
在viewLoad的程式區段寫入以下的程式碼(咦?第57行好像有行程式被藏起來了?!)

第67行程式碼表示把starTextField的輸入框模式為透過選單來填入資料。
第70–71行程式碼表示新增1個手勢按鈕並設定動作為第74–76行程式碼的函式,在畫面任一處點選就可以把這個View設為結束編輯模式,換句話說,就是把選單給收起來。

第11行程式碼加入UIPickerViewDelegate, UIPickerViewDataSource這2個,表示可以讓TrueLoveViewController可以使用UIPickerViewer的函式庫及指定UIPickerViewer資料來源為TrueLoveViewController。

接下來就是要設定UIPickerView的方法了。

寫到這裡時,可以先執行程式,當你點選星座的UITextField時,會出現星座選單,點選任一星座,就會被帶進UITextField的內容框,然後在畫面任一處點選,就會收起選單。

3. 程式會先判斷星座值及性別值是否有資料:
有-取得星座在陣列的位置,再與randomNum比對。
沒有-用UIAlertController做對話框視窗提醒使用者尚未選填資料。
4. 比對結果:
相同
-把名為yesImgView的UIImageView設定不隱藏,並把名為名為noImgView的UIImageView設定隱藏
不相同-把名為yesImgView的UIImageView設定隱藏,並把名為名為noImgView的UIImageView設定不隱藏

撰寫程式時,要養成防呆機制的習慣,避免使用者(特別是有心人)亂填資料導致程式崩潰,讓使用者留下不好的印象。

Apple Development / UISegmentedControl
UISegmentedControl是透過selectedSegmentIndex抓取值來判斷狀態:
未選取狀態之回傳值為 -1
若設定3個選項的話,回傳值分別為0, 1, 2,以此類推。
所以我們可以透過 [UISegmentedControl名稱].selectedSegmentIndex >= 0這行程式碼來判斷使用者是否選填。

Apple Development / String
UITextField則是計算該輸入文字的長度判斷是否有資料,所以我們可以用[UITextField名稱].text?.characters.count)! > 0 這行程式碼來判斷是否有資料。

第29行程式碼是抓取從starTextField抓取的值丟到星座陣列來找出該位置,再與randomNum比對。

[陣列名稱].index(of: [欲比對的物件內容])
為找出該物件在陣列的位置,並回傳Int型態的值。

第30–45行程式碼爲比對流程,其中第39–43行程式碼是在使用者未選填資料的情況,用UIAlertController做一個對話框視窗提醒使用者。
iOS8之前的版本,是用UIAlertView的Objective-C語法來撰寫,iOS8改用為UIAlertController的語法,讓使用者可以自訂對話框樣式及對話框按鈕。

Apple Development / UIAlertController
指定對話框畫面及樣式

let alertController = UIAlertController(title: “標題”, message: “內容”, preferredStyle: UIAlertControllerStyle.alert)

指定對話框按鈕,可以設定多個按鈕
let okAction = UIAlertAction(title: “按鈕標題”, style: UIAlertActionStyle.default)
let cancelAction = UIAlertAction(title: “按鈕標題”, style: UIAlertActionStyle.default)

新增對話框按鈕到對話框畫面
alertController.addAction(okAction)
alertController.addAction(cancelAction)

把對話框畫面加入目前的View
self.present(alertController, animated: true, completion: nil)

5. 上列邏輯跑完後,會立即啟動Timer,設定5秒後做下列的事情:
(1) 星座的UITextField資料清空。
(2) 性別的UISegmentedControl狀態設為未選取。
(3) yesImgView及noImgView設為隱藏。

第17行及第37行程式碼為宣告timer及方法。

Apple Development / Timer
scheduledTimer(timeInterval ti: TimeInterval, target aTarget: Any, selector aSelector: Selector, userInfo: Any?, repeats yesOrNo: Bool)

ti:每隔幾秒執行
target: 由誰執行(通常設定self)
selector: 執行函式
userInfo: 有些方法可能需要參數,透過這個來傳遞參數。
repeats: 是否重複執行。

恭喜你,又一個app完成了!Give me five!! 為你自己喝采!

不過,剛剛有提到第57行程式碼似乎被藏起來了,其實這是一個彩蛋。

bgImg是背景圖檔,有發現什麼端倪來了嗎?

沒錯,我有做12張背景圖檔,依序放上1~12顆星星來表示隨機產生的亂數是那一個星座在星座陣列的位置,所以每次開啟程式時看到背景圖檔有幾顆星星,就知道要選那一個星座囉!(謎之聲,好無聊的彩蛋。_。)

app完整程式專案下載

--

--