從純代碼UI -> 最初的Xib -> StoryBoard ,感受到UI的搭建也是逐漸可視化,簡單化。我是一個可視乎開發的支持者,有一些朋友不喜歡,這個純屬個人愛好,風格不同。
備註:本文代碼Demo使用Swift
# Xib基礎
## 1. UIStackView StackView 是iOS9以後纔有的,主要解決了組件排列布局複雜的問題,高效快速。
AutoLayout佈局是不是遇到過一個均分排列的佈局,還要隱藏顯示其中一個。 這樣佈局就很麻煩了,每次都要更改約束。
UIStackView主要有四個屬性:
- Axis(主軸是水平和垂直)
- Alignment
- Distribution
- Spacing
Alignment屬性
- Fill:完全充滿
- Top:頂部對齊
- Center:居中對齊
- Bottom:底部對齊
Distribution屬性
-
Fill:完全充滿
-
Fill Equally:均分填充,可是設置間隙,減去間隙均分填充滿。
-
Fill Proportionally:按照之前比例填充,可以設置間隙,減去間隙按比例充滿。
-
Fill Spacing:該屬性會保持子視圖的寬高,所有子視圖中間的間隔保持一致。
-
Fill Center: 該屬性是控制所有子視圖的中心之間的距離保持一致。
StackViewDemo
場景:動態Tab,可以展示2個也可以三個。
全部代碼和佈局如下圖:
2. AutoLayout 優先級和動畫
在沒有UISatckView之前,我們可以利用優先級完成三個Tab刪除一個的場景,但是再重新顯示是比較困難的。
約束優先級
先看下演示效果:
約束:三個Button等寬等高,均勻分佈到屏幕,關鍵點是Tab3的約束
優先級的作用簡單總結一下:一個元素可以同時存在兩個相同作用的約束,優先級必須有先後,當其中一個失效,另一個就會使用,這樣當我們刪除相關元素,可以導致優先級改變。
Tab3的優先級如下:
代碼:
@IBAction func deleteTab2BtnClick(_ sender: Any) {
priorityTab2.removeFromSuperview()
UIView.animate(withDuration: 3, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 15, options: .curveEaseInOut, animations: {
self.view.layoutIfNeeded()
}, completion: nil)
}
伸縮優先級
點擊控件我們在size inspector 一欄,最下部可以看到下面優先級。
Content Hugging Priority:表示一個控件“抗拉伸”的優先級。優先級越高,越不容易被拉伸,默認是:251。
Content Compression Resistance Priority:表示一個控件“抗壓縮”的優先級。優先級越高,越不容易被壓縮,默認是:750。
應用場景
最常見的簡單問題,如果我們需要在一行放兩個Label,Label寬度自適應。這樣就會報錯,因爲無法確定哪一個Label的寬度撐開的優先級高。
演示Demo:
兩個Label約束如下:
這時候就會報,上文所說的錯誤,修改一個優先級即可,我們想讓Label1拉伸,所有將Label2的抗拉伸優先級調高成252,同理你可以將Label1調成249。
還沒有結束,上述過程是空間充足的情況如果空間不足的話,還會出現報錯。
現在我們不希望Label2被壓縮,所以同理調高優先級即可。
3. @IBDesignable 和 @IBInspectable 的使用
應用場景:我們使用Xib綁定Custom Class想看一下樣子,所見即所得,IBDesignable這個屬性即可滿足這個需求。
有時候我們想在XIb裏直觀修改Xib屬性,但是Xcode並不全部提供屬性修改,可以通過Keypath修改,但是鍵入太麻煩容易出錯,所以可以通過IBInspectable添加自定義屬性。
應用Demo:
製作一個可以動態修改Raduis屬性,即可顯示的Demo。
import UIKit
@IBDesignable
class LayerView: UIView {
@IBInspectable var myRaduis:CGFloat = 0.0{
didSet{
self.layer.cornerRadius = myRaduis
}
}
}
# 視圖複用
1.自定義Xib View複用
Xcode 創建CocoaTouch Class View的時候,不可以自動生成綁定的Xib View。所以需要創建Xib View,然後綁定Custom Class。
step 1:
step 2:新建View Class,並在XIb綁定Custom Class爲該類。
step 3:使用該View
2,3步截圖使用代碼如下:
if let customView = Bundle.main.loadNibNamed("CustomView", owner: self, options: nil)?.first as? CustomView{
customView.frame = CGRect(x: 200, y: 500, width: 200, height: 100)
self.view.addSubview(customView)
}
2.在StoryBoard和Xib中怎麼複用Xib文件
上個例子中製作了一個Xib view,但是在項目中往往想更直接在StoryBoard中複用Xib view。直接關聯肯定是不行的。
下面介紹下如何在Sb中複用XIb 文件:
接上文例子,我們想在Sb中加上Xib view需要如下步驟,
step 1:綁定Xib 文件的 File's owner 的Class
step 2:在 init?(coder: NSCoder)初始化方法中,添加xib視圖。
import UIKit
class SbView: UIView {
required init?(coder: NSCoder) {
super.init(coder: coder)
if let sbView = Bundle.main.loadNibNamed("SbView", owner: self, options: nil)?.first as? UIView{
sbView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
self.addSubview(sbView)
}
}
}
step3: 在StoryBoard中,將該視圖綁定Class即可。
# StoryBoard
1.Segue
Segue是一個很簡單對象類,繼承於NSObject。目的也很簡單,主要是Sb VC之間跳轉關係的紐帶。
基本屬性:
屬性 | 作用 |
---|---|
identifier | 字符串標識,區分頁面不同Segue |
source | 跳轉之前的控制器 |
destination | 需要跳轉到的控制器 |
傳值:
有時候我們需要判斷是否滿足跳轉的條件,可以重寫UIViewController shouldPerformSegue
代理:
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
if identifier == "jumpSecond"{
return true
}
return false
}
傳值的時候,可以重寫prepare
方法。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "jumpSecond"{
let vc = segue.destination as? SecondViewController
vc?.title = "第二控制器"
}
}
下面一個圖可以清楚說明:
2.快捷TableViewController
一些簡單的表格頁面,比如設置頁面,可以使用靜態TableViewController,簡單高效。
應用Demo,設置頁面:
step1: 拖一個TableViewController,改成靜態的Cells,Style改成分組
step2: 修改Cell 爲想要的類型,然後複製Section Cell,修改數據,組合即可。
# Cocoapods 製作第三方庫,上傳Xib文件
Cocoapods庫製作的時候,Xib文件需要寫到資源裏,需要注意一下。
# ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
# A list of resources included with the Pod. These are copied into the
# target bundle with a build phase script. Anything else will be cleaned.
# You can preserve files from being cleaned, please don't preserve
# non-essential files like tests, examples and documentation.
#
# spec.resource = "icon.png"
spec.resources = "Classes/Cell/*.xib","Classes/Image/*.png"
# 展望
希望寫一個第三方庫,可以更方便的使用Interface Building去寫app,擴展更多更有用的可視化屬性和控件。 讓開發iOS 更簡單,高效。
拋磚引玉,希望有相同志向的人,能一起擴展完善。
第三方地址:XibKits