纯代码布局,也可以一样的简洁

前言

在前两篇文章讲述了UIStackView布局思想,使用方法以及一些实用的案例,在案例中使用xib结合UIStackView,缺少一些对纯代码的补充,这篇文章,我们主要聊聊如何使用StackView来写纯代码布局。

即便说过很多StackView的好,但是还是很多人认为复杂的页面用不上,其实真正理解了StackView的布局思想,不管是结构层级简单的布局亦或者复杂的布局,也不管是使用Inferface Builder来构建UI,还是使用纯代码,都能够游刃有余。

下面,我会使用swift演示使用纯代码是怎样布局的。如果有兴趣,点击下载Demo查看效果。下面所展示的代码只是截取的布局部分。

简单布局

简单布局,我归纳为,一行或者一列的元素组成的。通常有类页面如设置页、通讯录。如下布局中,一个hStack包含了image、label、button,组成了一个简单的布局。


结构如下:
HStack: image + label + Button

/// 懒加载 
private lazy var vStack = VStack(spacing: 16) 

Note: 这里的VStack实际上是对UIStackView的封装以及添加了便携式的初始化,并不是SwiftUIVStack

/// 布局代码
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])

NotesizeConstraint、heightConstraint、widthConstraint、addArrangedSubviewsMakeConstraint、spacer()这些都是自己添加分类方法。

嵌套布局

嵌套布局,我归纳为,界面的元素多样化,需要使用两个以上StackView的布局(不同排列方向)。

4ee15758b52c4fbc99c468cd5fbac4a2~tplv-k3u1fbpfcp-zoom-in-crop-mark-3024-0-0-0.image.png

结构如下:
HStack:image + VStack + Button
VStack:label + label

/// 懒加载
private lazy var hStack = HStack(spacing: 8, alignment: .center, distribution: .fill)
private lazy var vStack = VStack(spacing: 4, alignment: .fill, distribution: .fill)

Noteswift可以写出比OC更多的语法糖,这是语法的特性所在。从初始化方法上就可以看出。

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])

动态更新布局

动态更新布局,我归纳为,界面的元素多样化,一些界面上的元素会有种状态,继而影响到其他的元素,最终会影响到整体的布局。

ade55c3d9c7246828c6740ea41c35cf3~tplv-k3u1fbpfcp-zoom-in-crop-mark-3024-0-0-0.image.png

结构如下:
HStack:image + VStack + Button
VStack:HStack + label
HStack:label + label

其实整体的布局,与上面的例子中仅仅只有细微的差别,这里想要体现的是,修改stackView的属性以及修改stackView中的排列视图的width、height或者hidden相关的属性,都会使stackView重新布局。

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
    }
}
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。

有时候,写个简单的页面,真的不需要那么多代理,这不是更简单吗?

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纯代码布局是不是比想象中要香很多呢。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容