VStack、HStack、ZStack 实际上都是 @ViewBuilder,他们是返回 view 的函数,不允许为空。ViewBuilder 不绘制任何东西,它只是将不同的View组合到一起;但是加到 ViewBuilder 的修饰符,都会传递到它所包含的视图中去。关于 ViewBuilder 详细说明,请查看:‣
// alignment 和 spacing 可以设置对齐和间距
VStack(alignment: .leading, spacing: 10){
Text("Choose")
Text("Your Plan")
}
// 如果 VStack 堆栈中只有一个视图,并且不带任何参数,则可以将视图的初始值设定项直接传递给 VStack 以使代码更短:
if sizeClass == .compact {
VStack(content: UserView.init)
} else {
HStack(content: UserView.init)
}
//对齐第一个/最后一个单词
HStack(alignment: .firstTextBaseline){...}
HStack(alignment: .lastTextBaseline){...}
//等分内部区块:通过设置 maxWidth: .infinity, 保持不同区块的大小一致
HStack{
VStack{}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 100)
VStack{}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 100)
}.padding(.horizontal)
ZStack 是Z方向上的层级堆叠关系,嵌入在 ZStack 中的视图顺序,越后出现的越在界面的最前面。
ZStack 和 VStack和HStack一样,都是收缩视图,但有时它会被内部的 Color 视图撑开,让人误以为是扩张型视图。
**设置对齐:**ZStack 没有间距的概念,因为视图重叠,但它确实对齐。ZStack 的对齐是跟元素中,最大的那个元素对齐;所以当有一个大东西 ZStack 和一个小东西,你可以使两个视图都对齐到顶部,
**绝对定位:**绝对定位的视图,都可以用ZStack来实现。
ZStack(alignment: .topLeading) {...}
//调整某个具体元素的位置
ZStack{
Text("Copywriting")
.offset(x:0,y:80)
}
设置扩张:
//把 ZStack 扩张到整个手机屏幕
ZStack{}
.edgesIgnoringSafeArea(.all)
//如果不希望内容也扩张到安全区域外,可以只给背景视图加忽略标记,而不要在ZStack里加
ZStack {
Color.gray
.edgesIgnoringSafeArea(.all)
...
}
LazyVStack
& LazyHStack
被称为惰性堆栈。
因为 scrollView
里面的子元素,都是一开始就全部添加进视图的,即使在屏幕上看不见。SwiftUI 不会等到你向下滚动才能看到它们,它只会立即创建它们。如果想避免这种情况发生,可以为 VStack
和 HStack
提供一个替代方案,分别称为 LazyVStack
和 LazyHStack
。它们的使用方式与常规堆栈完全相同,但会按需加载其内容(在实际显示之前它们不会创建视图)。因此最大限度地减少了所使用的系统资源量。
ScrollView {
LazyVStack(spacing: 10) {
ForEach(0..<100) {
CustomText("Item \\($0)")
.font(.title)
}
}
.frame(maxWidth: .infinity)
}
<aside> 💡 尽管使用【常规堆栈】和【惰性堆栈】的代码是相同的,但有一个重要的布局差异:【惰性堆栈】始终占用布局中可用的空间,而【常规堆栈】仅占用所需空间。否则在【惰性堆栈】加载更多新视图时,它需要不断地调整尺寸大小。
</aside>
主要用于制作分割线,可以用 frame 来设置粗细。
Divider()
.frame(height: 1)
.background(Color(red: 240/255, green: 240/255, blue: 240/255))
.padding(.horizontal)
Spacer 弹性空间属于扩张型视图,主要用于填充空白。但也可以通过设置精确控制它的尺寸大小:
// 设置准确的高度
Spacer().frame(height: 50)
// 还可以指定最小和最大范围
Spacer()..frame(minHeight: 50, maxHeight: 500)
// 还可以通过 minLength 设置最小长度
Spacer(minLength: 0)
如何设置平分布局:
在一个视图中添加 N 个 Spacer ,其原理是将这个视图中的可用空间,分成N份,给到每一个Spacer。可以利用这一点来精细控制间隔。
//例如,我们可以在顶部留出三分之一的空间,在底部留出三分之二的空间,如下所示:
VStack {
Spacer()
Text("First")
Text("Second")
Text("Third")
Spacer()
Spacer()
}
//二等分布局
HStack {
Spacer()
VStack(alignment: .leading) {
Text("Rodrigo")
Text("Mark")
Text("Evans")
}.layoutPriority(1)
Spacer()
VStack(alignment: .leading) {
Text("Red")
Text("Orange")
Text("Green")
Text("Blue")
}.layoutPriority(1)
Spacer()
}
//三等分布局
VStack(spacing: 5) {
Spacer()
.frame(width: 5)
.background(Color.blue)
Text("33% Down")
Spacer()
.frame(width: 5)
.background(Color.blue)
Spacer()
.frame(width: 5)
.background(Color.blue)
}