mcpField
A
axiom-swiftui-containers-ref

axiom-swiftui-containers-ref

github.com/charleswiltgen设计与 UI1.2k192 次安装今天更新
代码仓库

关于 axiom-swiftui-containers-ref

axiom-swiftui-containers-ref 是面向 SwiftUI 开发者的容器布局参考技能,覆盖 iOS 14 至 iOS 26。它按列表、网格、层级数据和滚动需求介绍容器选择、常见模式及性能注意事项。

主要功能

  1. 01选择堆栈、网格与层级容器
  2. 02构建延迟加载的滚动列表
  3. 03实现网格和轮播布局
  4. 04展示可展开的层级数据
  5. 05使用滚动定位与过渡效果
  6. 06参考不同容器的性能建议

适用场景

  1. 01为大量项目构建滚动列表
  2. 02制作自适应照片网格
  3. 03显示文件树或可折叠选项
  4. 04为横向滚动内容添加吸附定位

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/charleswiltgen/axiom --skill axiom-swiftui-containers-ref

安装后在 Claude Code 中输入/axiom-swiftui-containers-ref确认已加载。

详细介绍

SwiftUI 容器参考

堆栈、网格、大纲和滚动增强功能。iOS 14 至 iOS 26。

来源:WWDC 2020-10031、2022-10056、2023-10148、2024-10144、2025-256

快速选择

用例容器iOS
固定视图的垂直/水平排列VStack / HStack13+
重叠视图ZStack13+
大型可滚动列表LazyVStack / LazyHStack14+
多列网格LazyVGrid14+
多行网格(水平)LazyHGrid14+
静态网格、精确对齐Grid16+
层级数据(树)带 children: 的 List14+
自定义层级结构OutlineGroup14+
显示/隐藏内容DisclosureGroup14+

第 1 部分:堆栈

VStack、HStack、ZStack
VStack(alignment: .leading, spacing: 12) {
    Text("Title")
    Text("Subtitle")
}

HStack(alignment: .top, spacing: 8) {
    Image(systemName: "star")
    Text("Rating")
}

ZStack(alignment: .bottomTrailing) {
    Image("photo")
    Badge()
}

ZStack 对齐方式:.center(默认)、.top、.bottom、.leading、.trailing、.topLeading、.topTrailing、.bottomLeading、.bottomTrailing

Spacer
HStack {
    Text("Left")
    Spacer()
    Text("Right")
}

Spacer(minLength: 20)  // Minimum size

LazyVStack、LazyHStack(iOS 14+)

仅在子视图可见时才渲染。请在 ScrollView 中使用。

ScrollView {
    LazyVStack(spacing: 0) {
        ForEach(items) { item in
            ItemRow(item: item)
        }
    }
}
固定分区标题
ScrollView {
    LazyVStack(pinnedViews: [.sectionHeaders]) {
        ForEach(sections) { section in
            Section(header: SectionHeader(section)) {
                ForEach(section.items) { item in
                    ItemRow(item: item)
                }
            }
        }
    }
}

第 2 部分:网格

Grid(iOS 16+)

非懒加载网格,可精确对齐。一次性加载所有视图。

Grid(alignment: .leading, horizontalSpacing: 10, verticalSpacing: 10) {
    GridRow {
        Text("Name")
        TextField("Enter name", text: $name)
    }
    GridRow {
        Text("Email")
        TextField("Enter email", text: $email)
    }
}

修饰符:

  • gridCellColumns(_:) — 跨越多列
  • gridColumnAlignment(_:) — 覆盖列对齐方式
Grid {
    GridRow {
        Text("Header").gridCellColumns(2)
    }
    GridRow {
        Text("Left")
        Text("Right").gridColumnAlignment(.trailing)
    }
}

LazyVGrid(iOS 14+)

垂直滚动网格。定义列;行数可无限增长。

let columns = [
    GridItem(.flexible()),
    GridItem(.flexible()),
    GridItem(.flexible())
]

ScrollView {
    LazyVGrid(columns: columns, spacing: 16) {
        ForEach(items) { item in
            ItemCard(item: item)
        }
    }
}
LazyHGrid(iOS 14+)

水平滚动网格。定义行;列数可无限增长。

let rows = [GridItem(.fixed(100)), GridItem(.fixed(100))]

ScrollView(.horizontal) {
    LazyHGrid(rows: rows, spacing: 16) {
        ForEach(items) { item in
            ItemCard(item: item)
        }
    }
}
GridItem.Size
大小行为
.fixed(CGFloat)精确宽度/高度
.flexible(minimum:maximum:)均匀填充可用空间
.adaptive(minimum:maximum:)尽可能多地创建项目
// Adaptive: responsive column count
let columns = [GridItem(.adaptive(minimum: 150))]

第 3 部分:大纲

使用层级数据的 List(iOS 14+)
struct FileItem: Identifiable {
    let id = UUID()
    var name: String
    var children: [FileItem]?  // nil = leaf
}

List(files, children: \.children) { file in
    Label(file.name, systemImage: file.children != nil ? "folder" : "doc")
}
.listStyle(.sidebar)
OutlineGroup(iOS 14+)

用于 List 之外的自定义层级布局。

List {
    ForEach(canvases) { canvas in
        Section(header: Text(canvas.name)) {
            OutlineGroup(canvas.graphics, children: \.children) { graphic in
                GraphicRow(graphic: graphic)
            }
        }
    }
}
DisclosureGroup(iOS 14+)
@State private var isExpanded = false

DisclosureGroup("Advanced Options", isExpanded: $isExpanded) {
    Toggle("Enable Feature", isOn: $feature)
    Slider(value: $intensity)
}

第 4 部分:常见模式

照片网格
let columns = [GridItem(.adaptive(minimum: 100), spacing: 2)]

ScrollView {
    LazyVGrid(columns: columns, spacing: 2) {
        ForEach(photos) { photo in
            AsyncImage(url: photo.thumbnailURL) { image in
                image.resizable().aspectRatio(1, contentMode: .fill)
            } placeholder: { Color.gray }
            .aspectRatio(1, contentMode: .fill)
            .clipped()
        }
    }
}
水平轮播
ScrollView(.horizontal, showsIndicators: false) {
    LazyHStack(spacing: 16) {
        ForEach(items) { item in
            CarouselCard(item: item).frame(width: 280)
        }
    }
    .padding(.horizontal)
}
文件浏览器
List(selection: $selection) {
    OutlineGroup(rootItems, children: \.children) { item in
        Label {
            Text(item.name)
        } icon: {
            Image(systemName: item.children != nil ? "folder.fill" : "doc.fill")
        }
    }
}
.listStyle(.sidebar)

第 5 部分:性能

何时使用懒加载
大小可滚动?使用
1-20否VStack/HStack
1-20是ScrollView 中的 VStack/HStack
20-100是LazyVStack/LazyHStack
100+是LazyVStack/LazyHStack 或 List
Grid <50否Grid
Grid 50+是LazyVGrid/LazyHGrid

缓存 GridItem 数组 — 在 body 外定义:

struct ContentView: View {
    let columns = [GridItem(.adaptive(minimum: 150))]  // ✅
    var body: some View {
        LazyVGrid(columns: columns) { ... }
    }
}
iOS 26 性能
  • 列表加载速度提升 6 倍,适用于 10 万项以上的列表
  • 列表更新速度提升 16 倍
  • 滚动时减少丢帧
  • 嵌套 ScrollView 与懒加载堆栈现在可正确延迟加载:
ScrollView(.horizontal) {
    LazyHStack {
        ForEach(photoSets) { set in
            ScrollView(.vertical) {
                LazyVStack {
                    ForEach(set.photos) { PhotoView(photo: $0) }
                }
            }
        }
    }
}

第 6 部分:滚动增强功能

containerRelativeFrame(iOS 17+)

根据滚动容器调整视图大小。

ScrollView(.horizontal) {
    LazyHStack {
        ForEach(cards) { card in
            CardView(card: card)
                .containerRelativeFrame(.horizontal, count: 3, span: 1, spacing: 16)
        }
    }
}
scrollTargetLayout(iOS 17+)

启用吸附效果。

ScrollView(.horizontal) {
    LazyHStack {
        ForEach(items) { ItemCard(item: $0) }
    }
    .scrollTargetLayout()
}
.scrollTargetBehavior(.viewAligned)
scrollPosition(iOS 17+)

跟踪最上方的可见项目。每个项目都必须有 .id()。

@State private var position: Item.ID?

ScrollView {
    LazyVStack {
        ForEach(items) { item in
            ItemRow(item: item).id(item.id)
        }
    }
}
.scrollPosition(id: $position)
scrollTransition(iOS 17+)
.scrollTransition { content, phase in
    content
        .opacity(1 - abs(phase.value) * 0.5)
        .scaleEffect(phase.isIdentity ? 1.0 : 0.75)
}
onScrollGeometryChange(iOS 18+)
.onScrollGeometryChange(for: Bool.self) { geo in
    geo.contentOffset.y < geo.contentInsets.top
} action: { _, isTop in
    showBackButton = !isTop
}
onScrollVisibilityChange(iOS 18+)
VideoPlayer(player: player)
    .onScrollVisibilityChange(threshold: 0.2) { visible in
        visible ? player.play() : player.pause()
    }

资源

WWDC:2020-10031、2022-10056、2023-10148、2024-10144、2025-256

文档:/swiftui/lazyvstack、/swiftui/lazyvgrid、/swiftui/lazyhgrid、/swiftui/grid、/swiftui/outlinegroup、/swiftui/disclosuregroup

技能:axiom-swiftui-layout、axiom-swiftui-layout-ref、axiom-swiftui-nav、axiom-swiftui-26-ref

评论

支持 Markdown