Skip to content

SwiftUI in iOS 15 (WWDC21)

A SwiftUI guide for coding agents. Also covers ios 15 swiftui features, swipeactions list, refreshable pull to refresh, searchable modifier, asyncimage remote image, focusstate text field, and 1 more.

Show all 7 aliases

ios 15 swiftui features, swipeactions list, refreshable pull to refresh, searchable modifier, asyncimage remote image, focusstate text field, canvas drawing materials

The iOS 15 SwiftUI release filled most of the long-standing gaps: list styling, swipe actions, pull to refresh, search, remote images, focus, drawing, and materials. Everything below is iOS 15 and macOS 12 and up.

List Upgrades

Separator styling and swipe actions arrived as modifiers.

Text(message)
  .listRowSeparatorTint(.red)
  .listRowSeparator(.visible, edges: .all)
  .swipeActions(edge: .trailing, allowsFullSwipe: false) {
    Button("Remove", role: .destructive) {
      messages.removeAll { $0 == message }
    }
  }

ButtonRole (.destructive, .cancel) styles the action; listSectionSeparator and listSectionSeparatorTint cover section separators.

List { /* rows */ }
  .refreshable { await reload() }
  .searchable("Search term", text: $query, placement: .automatic)

refreshable attaches the pull-to-refresh gesture; searchable wires the system search field into the navigation chrome.

AsyncImage and Markdown Text

AsyncImage(url:) downloads and shows a remote image through URLSession. Text accepts the new AttributedString, and markdown works in string literals too: Text("**Happy WWDC21**").

FocusState

First-responder control on iOS at last. Bind an optional field enum with @FocusState and mark each field with focused(_:equals:); setting the state moves the keyboard focus.

enum Field: Hashable { case usernameField, passwordField }
@FocusState private var focusedField: Field?

TextField("Username", text: $username)
  .focused($focusedField, equals: .usernameField)
SecureField("Password", text: $password)
  .focused($focusedField, equals: .passwordField)

Button("Sign In") {
  if username.isEmpty { focusedField = .usernameField }
  else if password.isEmpty { focusedField = .passwordField }
  else { handleLogin(username, password) }
}

Canvas, Materials, TimelineView

  • Canvas { context, size in ... } is the GPU-accelerated drawRect equivalent for paths, images, and text.
  • Materials bring the system blur surfaces: .background(.regularMaterial), from ultra-thin to ultra-thick.
  • TimelineView(PeriodicTimelineSchedule(from: start, by: 1)) re-renders on a schedule you define, for clocks and workout timers.

Also new: Accessibility Rotors and SectionedFetchRequest for Core Data.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-what-is-new-in-swiftui-after-wwdc21" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems