快速上手iOS UIKit UIKit是蘋果官方的framework, 其中包含了各種UI組件, window和view, 事件處理, 交互, 動畫, 資源管理等基礎設施支持. 按照前面的介紹, 用UIKit寫UI可以用storyboard(Interface Builder)和代碼兩種方式. 大體 ...
快速上手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
- https://codewithchris.com/swift-tutorial-complete/#uikit
- Programmatically Creating Constraints
出處: 博客園: 聖騎士Wind
Github: https://github.com/mengdd
微信公眾號: 聖騎士Wind