不使用第三方套件的前提下,客製化一個 TextField 動態提示文字 (Ver 1)

Marvin Lin
5 min readJul 4, 2018

--

寫在最前面:這個 UI 元件是第一版,目標是抽出固定會出現的元件,且這些元件還是能動且做到他本來該有的功能。不過我對這版程式碼還不是很滿意,要設定的東西還是太多,現在正在朝向修改 TextField Layer 的方向研究,希望第二版能直接做出一個 TextField 就有自己的動態提示文字,所以並不建議把這部分的程式碼直接用在上線的專案。

在某一天 UI 丟出了下面這樣的圖。

我轉頭問了一下 Android 工程師,他需要花多久時間完成這樣的設計。結果他淡定的說:「這是原生 UI 元件就有的功能」。不過 iOS 原生沒有這樣的功能,所以我只好自己用各種不同元件,組合出這樣的設計。

先從需求分析開始

  1. 當文字框內沒有字的時候,Placeholder 文字要在底線上方
  2. 當鍵盤彈出的時候,Placeholder 縮小字型並上移,然後變色。
  3. 當編輯結束的時候,如果 text field 裡面沒有字,Placeholder 移回原位且變回原色。
  4. 如果編輯結束有字,Placeholder 不移回原位但變回原色

看完上面這四點,我們可以用 UITextFieldDelegate裡面的方法來完成。

Apple 的文件裡面有詳細的說明。

optional func textFieldDidBeginEditing(_ textField: UITextField) //這裡執行 Placeholder label 的上移或變色optional func textFieldDidEndEditing(_ textField: UITextField) //這裡執行 Placeholder label 的下移或變色

但是...這個頁面只是第一頁的登入頁。過沒幾天,UI 丟了會員資料輸入的部分過來了,他大概長這樣。

當我看到了這個,我就知道如果我沒有把這個 UI 元件做出來,我就要在每一個 VC 上設定 textFieldDelegate,然後要用各種方式判斷不同的輸入點。不去想個比較好的方法,我光是調整每個 UI 元件的位置,時間就被吃光光了。

先從 Pods 套件來看,事實上,有「很像」這個 UI 的套件。就是 TextFieldEffects 的 Akira 效果。星星數有超過四千顆星,基本上應該是沒什麼問題 。

↓套件連結和展示

https://github.com/raulriera/TextFieldEffects

但這個套件並沒辦法百分之百的符合 UI 給的設計,所以最後我在修改套件和自己刻一個 UI 之間,我選擇了自己刻,因為 UI 是有要求字型也做變化,而且之後還對錯誤處理有特別的規範。

我用下面這個篇文章的方式,在一個 XIB 裡面塞了一個底線(UIView)、一個文字標題(UILabel)、和一個文字框(UITextField)。

但是因為 TextField 現在掛在 xib 的 containerView 底下,所以直接用 xib 的拖拉方式設定的 delegate所指向的 file owner,是指向給 DynamicView 這個物件。

外層的 ViewController 如果也想要知道 TextField 在 didBeginEditing 或 didEndEditing,就要做一個 DynamicView 的 delegate,然後指派給外層的 ViewController,讓 TextField 在把值傳給 DynamicView 的時候,再把值丟給外面的 VC。

但是,這樣的設計,是不是違反了 Apple 的 MVC 架構呢?

我覺得違反了,因為我把 delegate 設定給一個 view,雖這個 delegate 也只是把東西再傳一層出去。

因為有覺得違反 MVC 架構,所以我正在重新看 UITextField 裡面的 layer 和其他 API,看能不能直接把 title 的動態效果直接做在 Layer 裡面。如果完成了,會再寫一篇 Dynamic TextField (ver 2)。

全部的程式碼在下方,但目前有很大的改盡空間,所以並不建議在正式專案用這個方法。

--

--

Marvin Lin

突然有天對程式開始產生興趣,先從 Python 開始,然後轉入 Swift 。因為這個世界很有趣,所以我會不斷的推展我所接觸的領域。