Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

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 ↗

Transcript all transcripts

Code shown on screen · 12 snippets

Sandwich and HeroView swift · at 2:08 ↗
// 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 swift · at 2:26 ↗
// 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 swift · at 2:34 ↗
// 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 swift · at 2:39 ↗
// Fetch sandwiches from the sandwich store
let sandwiches: [Sandwich] = 

ScrollView {
    VStack(spacing: 0) {
        ForEach(sandwiches) { sandwich in
            HeroView(sandwich: sandwich)
        }
    }
}
Scrollable Stack of HeroViews swift · at 3:53 ↗
// 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 swift · at 3:57 ↗
// 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 swift · at 6:09 ↗
// 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 swift · at 6:18 ↗
// 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 swift · at 7:13 ↗
// 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 swift · at 8:47 ↗
struct GraphicsList: View {
    var graphics: [Graphic]
    var body: some View {
        List(
            graphics,
            children: \.children
        ) { graphic in
            GraphicRow(graphic)
        }
        .listStyle(SidebarListStyle())
    }
}
Customizing your outlines swift · at 9:52 ↗
// Customizing your outlines

List {
    ForEach(canvases) { canvas in
        Section(header: Text(canvas.name)) {
            OutlineGroup(canvas.graphics, children: \.children)
            { graphic in
                GraphicRow(graphic)
            }
        }
    }
}
DisclosureGroup swift · at 13:10 ↗
// Progressive display of information
Form {
    DisclosureGroup(isExpanded: $areFillControlsShowing) {
       Toggle("Fill shape?", isOn: isFilled)
       ColorRow("Fill color", color: fillColor)
    } label: {
       Label("Fill", )
    }
    
}

Resources