今天的聊天室練習遇到了許多的不順,還好經過了一個下午與 error 和 console 糾纏的過程之後
UI 介面總算是有個雛形了。
今天卡關卡了很久的點在於,要創建註冊資料輸入欄位時,定好 constraint 之後,用模擬器時模擬要進入輸入資料頁面時, APP 就 crush 掉了。找了很久都看不出是什麼原因。
程式碼如下
let nameTextField: UITextField = {
let tf = UITextField()
tf.placeholder = "Your name"
tf.translatesAutoresizingMaskIntoConstraints = false
tf.textAlignment = NSTextAlignment.center
return tf
}()
原生的 nameTextField 定位寫法是這樣:
nameTextField.leftAnchor.constraint(equalTo: inputContainerView.leftAnchor, constant: 12).isActive = true
nameTextField.widthAnchor.constraint(equalTo: inputContainerView.widthAnchor).isActive = true
nameTextField.heightAnchor.constraint(equalTo: inputContainerView.heightAnchor, multiplier: 1 / 3).isActive = true
nameTextField.topAnchor.constraint(equalTo: inputContainerView.topAnchor).isActive = true
inputContainerView.addSubview(nameTextField)
各位猜猜看為什麼會爆掉了嗎?
答案是 inputContainerView.addSubview(nameTextField) 這一段程式碼必須要寫在 nameTextField 的constraint 定位的前面。
因為在 xcode 的 Swift compiler 裡面,compiler 讀取程式碼是從上往下讀的。當 compiler 讀到我們要對nameTextField 這個物件定位(加入 constraint),然而, Swift 的 compiler 並不像許多其他語言的編譯器一樣,在找不到可以進行定位的 view 時,會自動指定一個 defualt 的 view 給他去執行。
所以當我把inputContainerView.addSubview(nameTextField) 寫在後面。所以 compiler 讀到了要加 constraint 的指令,卻找不到 nameTextField 上層的 view 可以去添加 constraint。所以此時 compiler 就會讓 APP crush 。
這在一開始是個十分讓人摸不著頭緒的 error ,不過只要把 inputContainerView.addSubview(nameTextField) 放到定位系統(constraint)的程式碼之前,compiler 就可以順利找到定位依據了!