2020 SwiftSwiftUI & UI Frameworks
WWDC20 · 19 min · Swift / SwiftUI & UI Frameworks
Stacks, Grids, and Outlines in SwiftUI
Display detailed data in your SwiftUI apps more quickly and efficiently with improved stacks and new list and outline views. Now available on iOS and iPadOS for the first time, outlines are a new multi-platform tool for expressing hierarchical data that work alongside stacks and lists. Learn how to use new and improved tools in SwiftUI to display more content on screen when using table views, create smooth-scrolling and responsive stacks, and build out list views for content that needs more than a vStack can provide. Take your layout options even further with the new grid view, as well as disclosure groups. To get the most out of this video, we recommend first checking out “SwiftUI App Essentials,” which provides an overview of everything new in SwiftUI for 2020. If you’re brand-new to coding with SwiftUI, we also suggest watching 2019’s “SwiftUI Essentials” talk.
Watch at developer.apple.com ↗Code shown on screen · 12 snippets
Sandwich and HeroView
// Sandwich model and gallery item view
struct Sandwich: Identifiable {
var id = UUID()
var name: String
var rating: Int
var heroImage: Image { … }
}
struct HeroView: View {
var sandwich: Sandwich
var body: some View {
sandwich.heroImage
.resizable()
.aspectRatio(contentMode: .fit)
.overlay(BannerView(sandwich: sandwich))
}
} Sandwich Info Banner
// Banner overlay view for sandwich info
struct BannerView: View {
var sandwich: Sandwich
var body: some View {
VStack(alignment: .leading, spacing: 10) {
Spacer()
TitleView(title: sandwich.name)
RatingView(rating: sandwich.rating)
}
.padding(…)
.background(…)
}
} Sandwich Rating View
// Sandwich rating view
struct RatingView: View {
var rating: Int
var body: some View {
HStack {
ForEach(0..<5) { starIndex in
StarImage(isFilled: rating > starIndex)
}
Spacer()
}
}
} Scrollable Stack of HeroViews
// Fetch sandwiches from the sandwich store
let sandwiches: [Sandwich] = …
ScrollView {
VStack(spacing: 0) {
ForEach(sandwiches) { sandwich in
HeroView(sandwich: sandwich)
}
}
} Scrollable Stack of HeroViews
// Fetch sandwiches from the sandwich store
let sandwiches: [Sandwich] = …
ScrollView {
VStack(spacing: 0) {
ForEach(sandwiches) { sandwich in
HeroView(sandwich: sandwich)
}
}
} Scrollable Lazy Stack of HeroViews
// Fetch sandwiches from the sandwich store
let sandwiches: [Sandwich] = …
ScrollView {
LazyVStack(spacing: 0) {
ForEach(sandwiches) { sandwich in
HeroView(sandwich: sandwich)
}
}
} Scrollable Lazy Stack of HeroViews
// Fetch sandwiches from the sandwich store
let sandwiches: [Sandwich] = …
ScrollView {
LazyVStack(spacing: 0) {
ForEach(sandwiches) { sandwich in
HeroView(sandwich: sandwich)
}
}
} Three-Column Grid of Sandwiches
// Fetch sandwiches from the sandwich store
let sandwiches: [Sandwich] = …
// Define grid columns
var columns = [
GridItem(spacing: 0),
GridItem(spacing: 0),
GridItem(spacing: 0)
]
ScrollView {
LazyVGrid(columns: columns, spacing: 0) {
ForEach(sandwiches) { sandwich in
HeroView(sandwich: sandwich)
}
}
} Adaptive Grid of Sandwiches
// Fetch sandwiches from the sandwich store
let sandwiches: [Sandwich] = …
// Define grid columns
var columns = [
GridItem(.adaptive(minimum: 300), spacing: 0)
]
ScrollView {
LazyVGrid(columns: columns, spacing: 0) {
ForEach(sandwiches) { sandwich in
HeroView(sandwich: sandwich)
}
}
} Outline of GraphicRows
struct GraphicsList: View {
var graphics: [Graphic]
var body: some View {
List(
graphics,
children: \.children
) { graphic in
GraphicRow(graphic)
}
.listStyle(SidebarListStyle())
}
} Customizing your outlines
// Customizing your outlines
List {
ForEach(canvases) { canvas in
Section(header: Text(canvas.name)) {
OutlineGroup(canvas.graphics, children: \.children)
{ graphic in
GraphicRow(graphic)
}
}
}
} DisclosureGroup
// Progressive display of information
Form {
DisclosureGroup(isExpanded: $areFillControlsShowing) {
Toggle("Fill shape?", isOn: isFilled)
ColorRow("Fill color", color: fillColor)
} label: {
Label("Fill", …)
}
…
} Resources
Related sessions
-
43 min -
27 min -
15 min -
36 min -
28 min -
58 min