Stack 堆栈

VStack、HStack、ZStack 实际上都是 @ViewBuilder,他们是返回 view 的函数,不允许为空。ViewBuilder 不绘制任何东西,它只是将不同的View组合到一起;但是加到 ViewBuilder 的修饰符,都会传递到它所包含的视图中去。关于 ViewBuilder 详细说明,请查看:‣

VStack

// 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

//对齐第一个/最后一个单词
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

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) 
	...
}

LazyStack 惰性堆栈

LazyVStack & LazyHStack 被称为惰性堆栈。

因为 scrollView 里面的子元素,都是一开始就全部添加进视图的,即使在屏幕上看不见。SwiftUI 不会等到你向下滚动才能看到它们,它只会立即创建它们。如果想避免这种情况发生,可以为 VStackHStack 提供一个替代方案,分别称为 LazyVStackLazyHStack 。它们的使用方式与常规堆栈完全相同,但会按需加载其内容(在实际显示之前它们不会创建视图)。因此最大限度地减少了所使用的系统资源量。

ScrollView {
	LazyVStack(spacing: 10) {
	    ForEach(0..<100) {
	        CustomText("Item \\($0)")
	            .font(.title)
	    }
	}
	.frame(maxWidth: .infinity)
}

<aside> 💡 尽管使用【常规堆栈】和【惰性堆栈】的代码是相同的,但有一个重要的布局差异:【惰性堆栈】始终占用布局中可用的空间,而【常规堆栈】仅占用所需空间。否则在【惰性堆栈】加载更多新视图时,它需要不断地调整尺寸大小。

</aside>


Divider 分割线

主要用于制作分割线,可以用 frame 来设置粗细。

Divider()
		.frame(height: 1)
    .background(Color(red: 240/255, green: 240/255, blue: 240/255))
    .padding(.horizontal)

Spacer 弹性空间

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)

}