Stack in SwiftUI

297 阅读3分钟

这一节很重要,因为在SwiftUI中,如果牵扯到布局,你就会使用它。那就是Stack。
Stack 分为 ZStack,VStack,HStack

  1. ZStack (zIndex,back to front) -> 层叠容器,它将其子视图放置在Z轴上,覆盖在一起。
  2. HStack (horizontal) -> 水平方向的堆叠容器,它将其子视图水平排列。
  3. VStack (horizontal) -> 竖直方向的堆叠容器,它将其子视图垂直排列

HStack

HStack是一个水平方向上的布局容器。它允许内部的子视图按照水平方式布局。

image.png

这是由两个圆形和一个长方形构成的布局,他们排列在水平方向上,它们之间的间隔是系统默认的间隔,默认为 8 ,如果你不想要间隔,可以使用把spacing 设置为 0 ,即可消除间隔。使用下面的方法即可

image.png

Stack 不但可以设置 Spacing,也可以设置对齐方式 alignment。比如上图就是以中心点为对齐方式,这是默认的对齐方式。我们可以改成 top 对齐。

image.png


VStack

我们把 HStackH 改成 V 就可以看到一个竖直方向上的布局

转存失败,建议直接上传图片文件

VStack 也有对齐方式,比如我们把 alignment 改成 leading

转存失败,建议直接上传图片文件

同样的方式来看看ZStack


ZStack

ZStack是一个zIndex的堆叠视图,它没有spacing参数

image.png

我们把 alignment 设置为 topleading

image.png


组合效果

image.png

说明:使用ZStack布局,ZStack容器里面有两个子视图,分别是一个全屏的Rectangle和一个VStackVStack内部有三个Rectangle

我们稍微改造以下

image.png

    struct StackSample: View {
        var body: some View {
            ZStack {
                Rectangle()
                    .fill(
                        LinearGradient(gradient: Gradient(colors: [Color.blue, Color.green]), startPoint: .topLeading, endPoint: .bottomTrailing)
                    )
                    .edgesIgnoringSafeArea(.all)
                
                VStack {
                    Rectangle()
                        .fill(Color.cyan)
                        .frame(width: 200, height: 200)
                    
                    Rectangle()
                        .fill(Color.green)
                        .frame(width: 150, height: 150)
                    
                    HStack  {
                        Circle()
                            .fill(Color.black)
                            .frame(width: 80, height: 80)
                        
                        Rectangle()
                            .fill(Color.black)
                            .frame(width: 130, height: 80)
                        
                        Circle()
                            .fill(Color.black)
                            .frame(width: 80, height: 80)
                    }
                }
            }
        }
    }

以上代码是ZStack的第二个视图的VStack中的最后一个视图变成了由两个圆形和一个长方形组成的HStack


以下是不同代码实现了相同的布局和效果
当我们在实现复杂布局时,我们可以使用Stack来完成难度较高的任务,如果简单的任务我们就用简单的布局容器来完成。

image.png

    struct StackSample: View {
        var body: some View {
            VStack(spacing: 50) {
                Text("5")
                    .font(.largeTitle)
                    .foregroundColor(Color.white)
                    .background(
                        Circle()
                            .fill(.purple)
                            .frame(width: 100, height: 100)
                    )
                
                ZStack {
                    Circle()
                        .fill(.blue)
                        .frame(width: 100, height: 100)
                    
                    Text("5")
                        .font(.largeTitle)
                        .foregroundColor(Color.white)
                }
            }
        }
    }

再给出一个相对复杂一点的例子,你来理解?如果有什么疑问,评论区见

image.png

    struct StackSample: View {
        var body: some View {
            ZStack {
                LinearGradient(gradient: Gradient(colors: [.blue, .purple]), startPoint: .top, endPoint: .bottom)
                    .edgesIgnoringSafeArea(.all)
                
                VStack(spacing: 20) {
                    HStack(spacing: 20) {
                        Image(systemName: "star.fill")
                            .foregroundColor(.yellow)
                            .font(.largeTitle)
                        Text("SwiftUI")
                            .foregroundColor(.white)
                            .font(.headline)
                    }
                    
                    VStack(spacing: 10) {
                        Text("Welcome to")
                            .foregroundColor(.white)
                        Text("Stack World!")
                            .foregroundColor(.white)
                            .font(.largeTitle)
                            .bold()
                    }
                    .padding()
                    .background(Color.black.opacity(0.5))
                    .cornerRadius(10)
                }
            }
        }
    }

总结:Stack是很重要的一个布局容器,很多地方会用到它。当我们实现一些复杂度较高的任务时,不妨多多想想Stack,多换几种方式。Stack可以组合出很多布局。