在 visionOS 中使用 Stack 实现灵活布局

探索如何在 visionOS 中利用 SwiftUI 的 Stack 组件(包括 HStack, VStack, 和 ZStack)来创建灵活且响应式的用户界面布局。

在 visionOS 中使用 Stack 实现灵活布局

在 visionOS 开发中,布局是构建用户界面的关键环节之一。Stack 组件是 SwiftUI 提供的一种强大而灵活的布局工具,用于垂直或水平排列子视图。在这篇文章中,我们将探讨如何在 visionOS 中使用 Stack 进行布局,并展示一些实际的应用场景。

什么是 Stack 组件?

在 SwiftUI 中,Stack 组件主要包括 HStackVStackZStack

每种 Stack 组件都有不同的用途和特性:

  • HStack:水平排列子视图。
  • VStack:垂直排列子视图。
  • ZStack:在 z 轴上堆叠子视图。

Stack 基本用法

示例代码

你可以在这里下载到这篇文章中使用到的所有演示代码,并在 Xcode 中的打开,尝试自己修改练习以确保正确理解。

GitHub - Jewel591/CodeWithIvens_Stack_Layout
Contribute to Jewel591/CodeWithIvens_Stack_Layout development by creating an account on GitHub.

如果对你有帮助,欢迎订阅我的博客哦!

使用 HStack 进行水平布局

HStack(水平堆栈)用于将子视图排列在一条水平线上。每个子视图都会按照声明的顺序从左到右排列。

import SwiftUI

struct HStackView: View {
    var body: some View {
        HStack {
            Image(systemName: "laptopcomputer")
                .resizable()
                .scaledToFit()
                .frame(width: 50, height: 50)
                .padding(.trailing, 10)
            Text("MacBook Pro 14")
                .font(.headline)
            Spacer() // Use a spacer to push everything to the edges
            Text("$1999")
                .font(.subheadline)
            Button(action: {
                // Action to add product to cart
                print("Added to cart")
            }) {
                Text("加入购物车")
                    .bold()
                    .foregroundColor(.white)
                    .padding(.horizontal, 12)
                    .padding(.vertical, 6)
                    .background(Color.blue)
                    .cornerRadius(10)
            }
        }
        .frame(maxWidth: 500)
        .padding()
    }
}

#Preview {
    HStackView()
}

使用 VStack 进行垂直布局

VStack(垂直堆栈)则是将子视图排列在一条垂直线上,子视图按照声明的顺序从上到下排列。

//
//  SwiftUIView.swift
//
//  Created by Ivens Liao on 2024/08/04.
//

import SwiftUI

struct VStackView: View {
    @State private var username: String = ""
    @State private var password: String = ""

    var body: some View {
        VStack(spacing: 20) {
            Text("会员登录")
                .font(.largeTitle)
                .bold()

            TextField("用户名", text: $username)
                .padding(.horizontal)

            SecureField("密码", text: $password)
                .padding(.horizontal)

            Button(action: {
                // 执行登录操作
                print("登录操作")
            }) {
                Text("登录")
                    .foregroundColor(.white)
                    .padding()
                    .cornerRadius(10)
            }
            .padding(.horizontal)
        }
        .frame(maxWidth: 400)
        .padding()
    }
}

#Preview {
    VStackView()
}

在这个示例中,VStack 将子视图垂直排列,并设置了每个子视图之间的间距为 20(spacing: 20)。

使用 ZStack 进行叠加布局

ZStack(Z 轴堆栈)用于将子视图层叠在一起,按照声明的顺序从底层到顶层排列。

在这个示例中,ZStack 将一个背景图片和文本视图叠加在一起,文本视图位于图标的上方。这样的卡片设计非常适合作为展示风景、广告或信息卡片等多种场景使用。

import SwiftUI

struct ZStackView: View {
    var body: some View {
        ZStack {
            Image("background")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: 300, height: 200)
                .cornerRadius(10)

            VStack(alignment: .leading, spacing: 8) {
                Spacer()
                Text("山川景色")
                    .font(.headline)
                    .foregroundColor(.white)
                    .shadow(radius: 1)
                    .padding(.horizontal)
                Text("这里是自然风光摄影爱好者的天堂,拥有丰富的地形和生态系统。")
                    .font(.subheadline)
                    .foregroundColor(.white)
                    .shadow(radius: 1)
                    .lineLimit(3)
                    .padding([.horizontal, .bottom])
            }
            .frame(maxWidth: .infinity, alignment: .leading)
        }
        .frame(width: 300, height: 200)
        .cornerRadius(10)
        .shadow(radius: 10)
    }
}

struct CardView_Previews: PreviewProvider {
    static var previews: some View {
        ZStackView()
    }
}

结合使用多种 Stack 组件

在实际开发中,常常需要结合使用 HStackVStack 来实现跟多样化的布局。

//
//  SwiftUIView.swift
//
//  Created by Ivens Liao on 2024/08/04.
//

import SwiftUI

struct StackView: View {
    var body: some View {
        VStack(spacing: 20) {
            Text("台北市")
                .font(.largeTitle)
                .bold()
            
            Text("26°C")
                .font(.system(size: 50, weight: .medium))
                .foregroundColor(.blue)
            
            HStack(spacing: 40) {
                VStack {
                    Image(systemName: "sun.max.fill")
                        .foregroundColor(.yellow)
                    Text("晴天")
                }
                
                VStack {
                    Image(systemName: "humidity.fill")
                        .foregroundColor(.blue)
                    Text("湿度 83%")
                }
            }
            
            Button(action: {
                // 刷新天气信息
                print("刷新天气")
            }) {
                Text("刷新")
                    .foregroundColor(.white)
                    .padding()
                    
                    .cornerRadius(10)
            }
            .padding(.horizontal)
        }
        .frame(maxWidth: 500)
        .padding()
    }
}

#Preview {
    StackView()
}

或者,像下面这样创建一个人物 Profile 简介视图: