+ 我要发布
我发布的 我的标签 发现
浏览器扩展
斑点象@Edge

使用 Stack 视图构建布局 - SwiftUI简体中文文档

使用 Stack 视图构建布局 通过原生容器视图构建复杂布局。 概览 单独的 HStack (英文)、VStack (英文) 和 ZStack (英文) 均属于简单视图。HStack (英文) 可以将视图置于水平线上,VStack (英文) 可以将视图置于垂直线上,而 ZStack (英文) 则可以将视图相互叠放。 当你使用默认参数初始化它们时,stack 视图会将其内容居中对齐,并在每个所含视图之间插入少量间隔。但是,当你使用视图修饰符 Spacer (英文) 和 Divider (英文) 视图合并和自定 stack 时,你可以创建高度灵活的复杂布局。 规划你的布局层次结构 当你开始将设计转换为代码时,在布局方面,请考虑可以如何使用各种类型的 stack 视图创建布局。将复杂设计细分为你可以通过 stack 视图构建的更小、更简单的部分。 例如,你可以使用三种 stack 视图构建以下个人资料视图: 示意图显示了普通用户个人资料布局如何利用 stack 视图。示意图显示了已渲染的布局,旁边是视图层次结构的三维分解图,其中展示了四层视图相互叠放。层次结构中的最低一层是 ZStack;在此之上是 Image 视图,然后是 HStack,最后是位于最高一层的 VStack 和 Spacer 视图。 ZStack (英文) 包含一个显示个人资料图片的 Image (英文) 视图,后者顶部叠加了一个半透明 HStack (英文)。HStack (英文) 包含一个 VStack (英文),后者内部有一对 Text (英文) 视图,Spacer (英文) 视图将 VStack (英文) 推向前缘侧。 若要创建这个 stack 视图,请使用以下代码: struct ProfileView: View { var body: some View { ZStack(alignment: .bottom) { Image("ProfilePicture") .resizable() .aspectRatio(contentMode: .fit) HStack { VStack(alignment: .leading) { Text("Rachael Chiseck") .font(.headline) Text("Chief Executive Officer") .font(.subheadline) } Spacer() } .padding() .foregroundColor(.primary) .background(Color.primary .colorInvert() .opacity(0.75)) } } } 通过 Alignment 和 Spacer 视图确定视图位置 通过组合使用 alignment 属性、Spacer (英文) 和 Divider (英文) 视图,对齐 stack 视图中包含的任意视图。 在前面的示例布局中,包含两个 Text (英文) 视图的 VStack (英文) 使用 leading (英文) 对齐: 示意图显示了两个视图在垂直 stack 视图中以三种不同方式对齐。左对齐,表示两个视图都与 stack 的前缘对齐。居中对齐,表示两个视图都在 stack 中居中对齐。最后是右对齐,表示两个视图都与后缘对齐 alignment 属性不会调整 VStack (英文) 相对于其父容器的布局,而是调整 VStack (英文) 内部视图的布局。 VStack (英文) 的 alignment 属性仅会应用于使用 HorizontalAlignment (英文) 对所含控件的水平对齐。同样,HStack (英文) 的 alignment 属性仅控制使用 VerticalAlignment (英文) 的垂直对齐。最后,你可以使用 Alignment (英文) 沿两个轴对齐 ZStack (英文) 中的视图。 Spacer (英文) 视图用于沿 HStack (英文) 或 VStack (英文) 的主轴对齐视图。Spacer 会进行扩展以填充所有可用空间,并将内容从其他视图或 stack 的边缘推开。 示意图显示了三个垂直 stack 视图中的 spacer 视图使用情况。第一个 stack 显示 spacer 视图将另一个视图推到其容器的顶部。第二个 stack 显示 spacer 视图将两个视图推开,使得这两个视图分别与其容器的顶部和底部对齐。spacer 视图将另一个视图推到其容器的底部。 Divider (英文) 视图还会在 stack 的子视图之间添加空间,但仅会插入足够沿 stack 的副轴绘制一条直线的空间。它们不会进行扩展来填充可用的空间。 创建自适应布局而不是显式布局 尽可能定义结构和层次结构,而不是显式确定视图框架的位置。不要为视图使用显式高度和宽度,而应让它们进行扩展以填充可用空间。你构建的自适应布局更容易适应不同的设备大小和平台。 通过以显式方式操控 Text (英文) 视图框架,可以使用两个而不是三个 stack 视图来创建这篇文章的示例布局。尽管输出看起来可能相同,但用来实施的代码更加脆弱,并且还可能无法在不同大小类别的设备之间进行缩放。 你可能需要使用 frame(width:height:alignment:) (英文) 或 position(x:y:) (英文) 等视图修饰符来对使用显式调整的布局进行调整,但仅当你无法以灵活的自适应方式获得所需布局才应考虑此方法。有关对视图布局进行精细调整的更多信息,请参阅“对视图的位置进行精细调整 (英文)”。 以替代方式添加深度 在某些情况下,可能需要使用 overlay(_:alignment:) (英文) 和 background(_:alignment:) (英文) 视图修饰符而不是 ZStack (英文) 来为你的布局添加深度。Background 视图修饰符将另一个视图置于你正在修饰的视图之后,overlay 则是在其顶部放置一个视图。 根据你想要如何确定最终布局的大小,在基于 stack 的方法和视图修饰符方法之间进行选择。如果你的布局有一个定义布局大小的主导视图,请在该视图上使用 overlay(_:alignment:) (英文) 或 background(_:alignment:) (英文) 视图修饰符。如果你想通过汇总所有所含视图得出最终视图大小,请使用 ZStack (英文)。 例如,以下代码会在 Image (英文) 视图的顶部叠加一个 ProfileDetail 视图: struct ProfileViewWithOverlay: View { var body: some View { VStack { Image("ProfilePicture") .resizable() .aspectRatio(contentMode: .fit) .overlay(ProfileDetail(), alignment: .bottom) } } } struct ProfileDetail: View { var body: some View { HStack { VStack(alignment: .leading) { Text("Rachael Chiseck") .font(.headline) Text("Chief Executive Officer") .font(.subheadline) } Spacer() } .padding() .foregroundColor(.primary) .background(Color.primary .colorInvert() .opacity(0.75)) } }