純程式碼佈局,也可以一樣的簡潔
theme: juejin highlight: xcode
“我報名參加金石計劃1期挑戰——瓜分10萬獎池,這是我的第3篇文章,點選檢視活動詳情”
前言
在前兩篇文章講述了UIStackView佈局思想,使用方法以及一些實用的案例,在案例中使用xib結合UIStackView,缺少一些對純程式碼的補充,這篇文章,我們主要聊聊如何使用StackView來寫純程式碼佈局。
即便說過很多StackView的好,但是還是很多人認為複雜的頁面用不上,其實真正理解了StackView的佈局思想,不管是結構層級簡單的佈局亦或者複雜的佈局,也不管是使用Inferface Builder
來構建UI,還是使用純程式碼,都能夠遊刃有餘。
下面,我會使用swift演示使用純程式碼是怎樣佈局的。如果有興趣,點選下載Demo檢視效果。下面所展示的程式碼只是擷取的佈局部分。
簡單佈局
簡單佈局,我歸納為,一行或者一列的元素組成的。通常有類頁面如設定頁、通訊錄。如下佈局中,一個hStack包含了image、label、button,組成了一個簡單的佈局。
結構如下:\ HStack: image + label + Button
swift
/// 懶載入
private lazy var vStack = VStack(spacing: 16)
Note: 這裡的
VStack
實際上是對UIStackView的封裝以及添加了行動式的初始化,並不是SwiftUI
中VStack
。
```swift /// 佈局程式碼 addSubview(hStack) hStack.snp.makeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)) }
/// 這裡是使用的擴充套件方法 iconView.sizeConstraint = CGSize(width: 40, height: 40) title.heightConstraint = 30 follow.sizeConstraint = CGSize(width: 60, height: 30) hStack.addArrangedSubviewsMakeConstraint([iconView, title, hStack.spacer(), follow]) ```
Note:
sizeConstraint、heightConstraint、widthConstraint、addArrangedSubviewsMakeConstraint、spacer()
這些都是自己新增分類方法。
巢狀佈局
巢狀佈局,我歸納為,介面的元素多樣化,需要使用兩個以上StackView的佈局(不同排列方向)。
結構如下:\ HStack:image + VStack + Button\ VStack:label + label
swift
/// 懶載入
private lazy var hStack = HStack(spacing: 8, alignment: .center, distribution: .fill)
private lazy var vStack = VStack(spacing: 4, alignment: .fill, distribution: .fill)
Note:
swift
可以寫出比OC
更多的語法糖,這是語法的特性所在。從初始化方法上就可以看出。
```swift addSubview(hStack) hStack.snp.makeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)) }
iconView.sizeConstraint = CGSize(width: 50, height: 50) helpView.sizeConstraint = CGSize(width: 30, height: 30) hStack.addArrangedSubviewsMakeConstraint([iconView, vStack, hStack.spacer(), helpView]) vStack.addArrangedSubviews([title, detail]) ```
動態更新佈局
動態更新佈局,我歸納為,介面的元素多樣化,一些介面上的元素會有種狀態,繼而影響到其他的元素,最終會影響到整體的佈局。
結構如下:\ HStack:image + VStack + Button\ VStack:HStack + label\ HStack:label + label
其實整體的佈局,與上面的例子中僅僅只有細微的差別,這裡想要體現的是,修改stackView的屬性以及修改stackView中的排列檢視的width、height或者hidden相關的屬性,都會使stackView重新佈局。
```swift private lazy var hStack = HStack(spacing: 8, alignment: .center, distribution: .fill) private lazy var vStack = VStack(spacing: 4, alignment: .fill, distribution: .fill) private lazy var titleHStack = HStack(spacing: 4, alignment: .center, distribution: .fill)
private var isFollow: Bool = false { didSet { self.follow.isHidden = isFollow self.followLabel.isHidden = !isFollow } } ```
```swift addSubview(hStack) hStack.snp.makeConstraints { make in make.edges.equalToSuperview().inset(UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)) }
iconView.sizeConstraint = CGSize(width: 50, height: 50) follow.sizeConstraint = CGSize(width: 60, height: 30) hStack.addArrangedSubviewsMakeConstraint([iconView, vStack, hStack.spacer(), follow]) vStack.addArrangedSubviews([titleHStack, detail])
followLabel.sizeConstraint = CGSize(width: 50, height: 15) titleHStack.addArrangedSubviewsMakeConstraint([title, followLabel, titleHStack.spacer()]) ```
滾動佈局
StackView有時候也可以使用配合ScrollView
一起使用,效果如同TableView,但是這個則需要使用好ScrollView的contentSize
,使用frame佈局,則需要手動設定;使用自動佈局,則需要ScrollView中的contentView來填充,最終ScrollView的contentSize取決於contentView。
有時候,寫個簡單的頁面,真的不需要那麼多代理,這不是更簡單嗎?
```swift view.addSubview(scrollView) scrollView.snp.makeConstraints { make in make.edges.equalTo(view.safeAreaLayoutGuide) }
scrollView.addSubview(vStack) vStack.snp.makeConstraints { make in make.edges.equalToSuperview(); make.width.equalToSuperview() } ```
結尾
文章使用了幾個簡單的例項,一點點的演變了不同的佈局方式,在我們日常開發中,或許有那些簡單極致的頁面,或許也有那些花裡胡哨的頁面,不管如何,佈局的思路都不會變,其實從例項中可以看出,佈局程式碼所佔篇幅並不多,在配合使用一些擴充套件類,其實使用StackView純程式碼佈局是不是比想象中要香很多呢。
- LeetCode 初級演算法之陣列(上),看看你都學會了嗎?
- LeetCode 初級演算法之連結串列,看看你都學會了嗎?
- LeetCode 初級演算法之字串(上),看看你都學會了嗎?
- 純程式碼佈局,也可以一樣的簡潔
- UIStackView之一問一答
- 使用UIStackView來簡化iOS的介面佈局
- 夏天來了,iOS開發者們該如何減少App耗電?(上)
- 夏天來了,App開發者們如何看待手機發燙問題?
- 聊聊iOS中UITableView複用的那些事
- 曾經經典的微信打飛機遊戲還有人記得嗎?
- iOS 原生渲染與 Flutter 有什麼區別 (上)
- 瞭解 Mach-O檔案
- CocoaPods中podsepc檔案設定詳解
- iOS 原生渲染與 Flutter 有什麼區別 (下)
- 簡單瞭解 iOS CVPixelBuffer (上)
- 談談 iOS 包瘦身方案
- 播放器重構的探索之路
- 如何使用CocoaPods製作私有庫
- iOS 元件化方案