[Android開發學iOS系列] 快速上手UIKit
快速上手iOS UIKit
UIKit是蘋果官方的framework, 其中包含了各種UI組件, window和view, 事件處理, 交互, 動畫, 資源管理等基礎設施支援.
按照前面的介紹, 用UIKit寫UI可以用storyboard(Interface Builder)和程式碼兩種方式.
大體的思路都是添加組件後, 設置屬性, 設置尺寸位置約束, 處理響應事件.
這裡主要介紹用程式碼寫的情形.
希望這篇文章, 可以幫你快速上手UIKit, 熟悉常用的組件, 完成一些簡單的UI介面相關任務.
在程式碼中寫UI的基本步驟
在程式碼中寫UI的步驟大致是:
- 初始化.
- addSubview添加到當前view, 或hierarchy中的其他可達view.
- 設置約束.
比如:
class ViewController: UIViewController {
var myLabel: UILabel!
override func loadView() {
view = UIView()
view.backgroundColor = .white
// 創建實例
myLabel = UILabel()
myLabel.translatesAutoresizingMaskIntoConstraints = false
myLabel.text = "Hello"
// 添加到view中
view.addSubview(myLabel)
// 設置約束
NSLayoutConstraint.activate([
myLabel.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),
myLabel.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
])
}
}
這裡有幾點說明:
var** myLabel: UILabel!
組件欄位這樣聲明有lateinit的作用, 如果不帶!會報錯, 說controller沒有init方法.- 如果在程式碼中設置UI組件的constraints, 那麼這個屬性經常要設置為false:
translatesAutoresizingMaskIntoConstraints = **false**
. 如果組件的位置是通過frame來設置的, 則不用設置這個屬性. - 約束有多種寫法, 這裡只是其中一種, 用anchor的方式.
常用組件
文字: UILabel
設置文字等屬性:
myLabel = UILabel()
myLabel.translatesAutoresizingMaskIntoConstraints = false
myLabel.font = UIFont.systemFont(ofSize: 24)
myLabel.text = "Hello"
myLabel.numberOfLines = 0
myLabel.textAlignment = .right
給UILabel設置點擊事件:
myLabel.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(userDidTapLabel(tapGestureRecognizer:)))
myLabel.addGestureRecognizer(tapGesture)
點擊事件處理方法:
@objc func userDidTapLabel(tapGestureRecognizer _: UITapGestureRecognizer) {
print("label clicked!")
}
這裡有#selector
, 對應的userDidTapLabel方法要加上@objc
. 便於OC的程式碼調用能找到swift的方法.
給UILabel設置點擊事件和UIButton不同, 這點我們後面說繼承關係的時候解釋一下.
按鈕: UIButton
設置文字:
submitButton = UIButton(type: .system)
submitButton.translatesAutoresizingMaskIntoConstraints = false
submitButton.titleLabel?.font = UIFont.systemFont(ofSize: 36)
submitButton.setTitle("SUBMIT", for: .normal)
submitButton.setTitleColor(.black, for: .normal)
設置點擊事件:
submitButton.addTarget(self, action: #selector(submitTapped), for: .touchUpInside)
@objc func submitTapped(_ sender: UIButton) {
}
這裡使用@objc
的理由同上.
基本上我們在iOS程式碼中用到#
的時候, 對應的方法都要加上@objc
.
輸入框: UITextField
myTextField = UITextField()
myTextField.translatesAutoresizingMaskIntoConstraints = false
myTextField.placeholder = "What's your name?"
myTextField.textAlignment = .center
myTextField.font = UIFont.systemFont(ofSize: 44)
想要禁用輸入框可以這樣:
myTextField.isUserInteractionEnabled = false
彈框
在app里簡單的交互我們經常需要彈出一個對話框:
let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Ok", style: .default))
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))
present(alert, animated: true)
其中preferredStyle有.alert
和.actionSheet
兩種.
.alert
是中心的對話框, 一般用於資訊提示或者確認操作; .actionSheet
是底部的bottom sheet, 一般用來在幾個選項中做選擇.
其他
- view中比較常用的屬性
isHidden
, 控制view是否需要隱藏. - 所有的UIView都有一個
layer
屬性.
設置border的寬度和顏色就在layer上設置.
CALayer在UIView之下. 所以不知道UIColor, 只知道CGColor.
本文僅列出幾個常用組件, 更多的請看官方示例.
繼承關係
NSObject
是所有Cocoa Touch class的基類. 所有UIKit中的類都是它的子類.
這裡有一個類關係的圖:
我們這裡不展開講述所有了, 只解答一下前面提出的關於UILabel點擊事件的問題.
這裡可以看到UILabel
和UIButton
雖然都繼承了UIView
, 但是UIButton
的繼承層次更深一些, 它還繼承了了UIControl
.
可以看到和UIButton平級的還有好幾個子類.
Controls使用的是target-action機制, 所有的action都通過方法: addTarget(_:action:for:)
添加.
約束Constraints
當在程式碼中設置約束時, 有三種選擇:
- 使用layout anchors.
- 使用
NSLayoutConstraint
類. - 使用Visual Format Language.
上面我們提到過的就是其中Layout Anchors的寫法:
初級單個寫法:
buttonsView.topAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
buttonsView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
buttonsView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
buttonsView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
放進數組裡批量激活寫法:
NSLayoutConstraint.activate([
buttonsView.topAnchor.constraint(equalTo: view.centerYAnchor),
buttonsView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
buttonsView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
buttonsView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
])
感覺是對新手比較直觀的一種寫法.
其他寫法文末有參考文檔.
PS: 項目中更流行用 SnapKit.
區域限制
safeAreaLayoutGuide
: 去掉圓角和劉海.layoutMarginsGuide
: safe area的內部再加上一些額外的margin.
Bonus
- 友情提示: 在xcode里就可以看官方文檔, 快捷鍵是
Cmd + Shift + 0
.
References
- UIKit Documentation
- UIKit Catalog
- //codewithchris.com/swift-tutorial-complete/#uikit
- Programmatically Creating Constraints