Skip to content

What Is New After WWDC 24 (SwiftUI)

A SwiftUI guide for coding agents. Also covers ios 18 swiftui features, tab type sidebaradaptable, zoom navigation transition, entry macro environment, previewable state macro, group subviewsof.

The iOS 18 generation of SwiftUI adds view-collection access, a new tab API, hero transitions, programmatic scroll position, and two boilerplate-killing macros. One breaking change leads: the App, Scene, and View protocols are now @MainActor isolated, which can break existing code.

View Collections

Group(subviewsOf:) gives a container access to the subviews a @ViewBuilder closure produced, through the new Subview and SubviewsCollection proxy types. This is the hook for building custom containers like List.

Group(subviewsOf: content) { subviews in
  HStack {
    if !subviews.isEmpty { subviews[0] }
    if subviews.count > 1 { subviews[1] }
  }
  if subviews.count > 2 {
    VStack { subviews[2...] }
  }
}

The Tab Type

Tab replaces tabItem, takes a selection value directly, and TabSection groups tabs. With .tabViewStyle(.sidebarAdaptable) the tab bar can flow into a sidebar.

TabView {
  Tab("home", systemImage: "home", value: Destination.home) {
    HomeView()
  }

  TabSection("Other") {
    Tab("settings", systemImage: "settings", value: Destination.settings) {
      SettingsView()
    }
  }
  .tabViewStyle(.sidebarAdaptable)
}

Hero Animations

Pair matchedTransitionSource on the NavigationLink label with navigationTransition(.zoom) on the destination, sharing an id and a @Namespace.

@Namespace var hero

NavigationLink {
  DetailView()
    .navigationTransition(.zoom(sourceID: "myId", in: hero))
} label: {
  ThumbnailView()
}
.matchedTransitionSource(id: "myId", in: hero)

Scroll Position

The ScrollPosition type with the scrollPosition modifier reads the exact offset and scrolls programmatically by setting the state.

@State private var position: ScrollPosition = .init(point: .zero)

ScrollView { /* content */ }
  .scrollPosition($position)

Button("jump to top") {
  position = ScrollPosition(point: .zero)
}

Entry and Previewable Macros

@Entry collapses the EnvironmentKey plus computed-property dance into one line, and it also works for focused and container values. @Previewable puts @State directly in a preview without a wrapper view.

extension EnvironmentValues {
  @Entry var itemsPerPage: Int = 10
}
#Preview("toggle") {
  @Previewable @State var toggled = true
  return Toggle("Loud Noises", isOn: $toggled)
}

Also new: window pushing, text selection observation, search focus monitoring, custom text rendering, and MeshGradient.

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-after-wwdc24" })
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