Pure code layout can also be as concise

"I signed up to participate in the 1st challenge of the Golden Stone Project - to share the 100,000 prize pool. This is my 3rd article, click to view the details of the event "

foreword

In the first two articles, I described the layout ideas, usage methods and some practical cases of UIStackView. In the case, the use of xib combined with UIStackView lacks some supplements to pure code. In this article, we mainly talk about how to use StackView to write pure code. layout.

Even though I have said a lot about the goodness of StackView, many people still think that complex pages are not useful. In fact, they really understand the layout idea of ​​StackView, whether it is a simple layout or a complex layout, or whether it is used Inferface Builderto build UI, Or use pure code, you can do it with ease.

Below, I will use swift to demonstrate how the layout is done using pure code. If you are interested, click to download Demo to see the effect. The code shown below is just a screenshot of the layout.

Simple layout

Simple layout, I summarize it as a row or a column of elements. Usually there are class pages such as settings page and address book. In the following layout, an hStack contains image, label, and button to form a simple layout.

The structure is as follows:
HStack: image + label + Button

/// 懒加载 
private lazy var vStack = VStack(spacing: 16) 
复制代码

Note : This is VStackactually the encapsulation of UIStackView and the addition of portable initialization, not SwiftUImedium VStack.

/// 布局代码
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()These are all methods of adding classification by yourself.

Nested layout

Nested layout, I summarize it, the elements of the interface are diversified, and it is necessary to use more than two StackView layouts (different arrangement directions).

结构如下:
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])
复制代码

动态更新布局

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

结构如下:
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。

Simulator Screen Recording - iPhone 14 Pro - 2022-09-18 at 23.22.56.gif

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

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

Guess you like

Origin juejin.im/post/7144754427637792781