MacKuba

Kuba Suder's blog on Mac & iOS development

What's new in SwiftUI

Categories: SwiftUI, WWDC 20 0 comments Watch the video

App & scene definition:

The whole app can now be built with SwiftUI, including what was previously in app delegate:

@main
struct HelloWorld: App {
    var body: some Scene {
        WindowGroup {
            ...
        }
    }
}

A WindowGroup renders as a single window on iPhone and Watch, on iPad it supports the new multi-window scene system, and on the Mac it creates multiple Mac windows

Settings – creates Mac preferences windows:

#if os(macOS)
    Settings {
        PreferencesList()
    }
#endif

For document-based apps:

@main
struct ShapeEditApp: App {
    var body: some Scene {
        DocumentGroup(newDocument: SketchDocument()) { file in
            DocumentView(file.$document)
        }
    }
}

Defining menu commands:

.commands {
    CommandMenu("Shape") {
        Button("Add Shape", action: { ... })
            .keyboardShortcut("N")
        ...
    }
}

New multiplatform Xcode project template that creates one SwiftUI app for all platforms

New “Launch Screen” Info.plist key

Lets you define launch screen elements like background, navigation bar, tab bar

Replacement for the launch storyboard for SwiftUI apps that don't otherwise have storyboards

New API for widgets:

@main
struct RecommendedAlbum: Widget {
    var body: some WidgetConfiguration {
        ...
    }
}

Complications for Apple Watch can now also be built using SwiftUI

Outlines (hierarchical lists):

List(graphics, children: \.children) { … }

Grids:

LazyVGrid(columns: [GridItem(.adaptive(minimum: 176))]) { … }
-> adapts number of columns to view size

LazyVGrid(columns: Array(repeating: GridItem(), count: 4)) { }
-> fixed number of columns

Also horizontally loading grids

Lazy versions of the existing stack views: LazyVStack, LazyHStack

Toolbars:

.toolbar {
    Button(action: { ... }) { Label("Record", systemImage: ...)
    // placed automatically in an appropriate place

    ToolbarItem(placement: .primaryAction) {
        Button(...)
    }
}

ToolbarItem has various semantic names for placement like principal, confirmationAction, bottomBar

Labels:

Label(“Books”, systemImage: “book.circle”)
Label { Text(“…”) } icon: { Image(systemName: “…”) }
  • combines an icon with a title and shows them appropriately for the context

.help(“Does something”) – tooltips on macOS, voiceover comment on iOS

.keyboardShortcut(“X”)

.keyboardShortcut(.cancelAction / .defaultAction)

New support for focus on tvOS

ProgressView – spinner or progress bar

Gauge – on watchOS, the circular meter control from complications

.matchedGeometryEffect(id: albumId, in: namespace) – animates a view from one view hierarchy into another

.clipShape(ContainerRelativeShape()) – applies rounded corners matching the parent view

Text – custom fonts are now adapted to Dynamic Type

Images can be embedded inside text and are scaled with it

@ScaledMetric var padding – a value defined by you that is scales with Dynamic Type

App accent color can now be set in the asset catalog

Support for accent color on the Mac

.listItemTint() customizes the color for a section or item

Tint parameter in control styles: .toggleStyle(SwitchToggleStyle(tint: .accentColor))

Link(destination: url) { Label(…) } – a link label that opens a URL in Safari

@Environment(\.openURL) var openURL – provides a openURL(url) function

UniformTypeIdentifiers framework provides content type identifiers for drag & drop

SignInWithAppleButton()

SwiftUI views for: AVKit, MapKit, SceneKit, SpriteKit, QuickLook, HomeKit, ClockKit, StoreKit, WatchKit