[ad_1]
Earlier this week, Apple kicked off WWDC 22. The SwiftUI framework continues to be one of many major focuses of the convention. As anticipated, Apple introduced a brand new model of SwiftUI that comes together with iOS 16 and Xcode 14.
This replace comes with tons of options to assist builders construct higher apps and write much less code. On this tutorial, let me offer you an outline of what’s new in SwiftUI 4.0.
SwiftUI Charts
You not have to construct your individual chart library or depend on third-party libraries to create charts. The SwiftUI framework now comes with the Charts APIs. With this declarative framework, you possibly can current animated charts with just some strains of code.
In short, you construct SwiftUI Charts by defining what it calls Mark. Here’s a fast instance:
struct ContentView: View {
var physique: some View {
Chart {
BarMark(
x: .worth(“Day”, “Monday”),
y: .worth(“Steps”, 6019)
)
BarMark(
x: .worth(“Day”, “Tuesday”),
y: .worth(“Steps”, 7200)
)
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import SwiftUI import Charts  struct ContentView: View {     var physique: some View {         Chart {             BarMark(                 x: .worth(“Day”, “Monday”),                 y: .worth(“Steps”, 6019)             )              BarMark(                 x: .worth(“Day”, “Tuesday”),                 y: .worth(“Steps”, 7200)             )         }     } } |
Whether or not you need to create a bar chart or line chart, we begin with the Chart view. Contained in the chart, we outline the bar marks to offer the chart knowledge. The BarMark view is used for making a bar chart. Every BarMark view accepts the x and y worth. The x worth is used for outlining the chart knowledge for x-axis. Within the code above, the label of the x-axis is ready to Day. The y axis exhibits the full variety of steps.
In the event you enter the code in Xode 14, the preview routinely shows the bar chart with two vertical bars.

The code above exhibits you the only technique to create a bar chart. Nonetheless, as an alternative of hardcoding the chart knowledge, you normally use the Charts API with a group of information. Right here is an instance:

By default, the Charts API renders the bars in the identical shade. To show a special shade for every of the bars, you possibly can connect the foregroundStyle modifier to the BarMark view:
|
.foregroundStyle(by: .worth(“Day”, weekdays[index])) |
So as to add an annotation to every bar, you utilize the annotation modifier like this:
|
.annotation { Â Â Â Â Textual content(“(steps[index])“) } |
By making these adjustments, the bar chart turns into extra visually interesting.

To create a horizontal bar chart, you possibly can merely swap the values of x and y parameter of the BarMark view.

By altering the BarMark view to LineMark, you possibly can flip a bar chart right into a line chart.
|
Chart {     ForEach(weekdays.indices, id: .self) { index in         LineMark(             x: .worth(“Day”, weekdays[index]),             y: .worth(“Steps”, steps[index])         )         .foregroundStyle(.purple)         .lineStyle(StrokeStyle(lineWidth: 4.0))     } } |
Optionally, you utilize foregroundStyle to vary the colour of the road chart. To alter the road width, you can even connect the lineStyle modifier.
The Charts API is so versatile that you could overlay a number of charts in the identical view. Right here is an instance.

Apart from BarMark and LineMark, the SwiftUI Charts framework additionally offers PointMark, AreaMark, RectangularMark, and RuleMark for creating several types of charts.
Resizable Backside Sheet
Apple launched UISheetPresentationController in iOS 15 for presenting an expandable backside sheet. Sadly, this class is barely obtainable in UIKit. If we need to use it in SwiftUI, now we have to put in writing further code to combine the part into SwiftUI tasks. This 12 months, Swift comes with a brand new modifier referred to as presentationDetents for presenting a resizable backside sheet .
To make use of this modifier, you simply want to put this modifier inside a sheet view. Right here is an instance:
var physique: some View {
VStack {
Button(“Present Backside Sheet”) {
showSheet.toggle()
}
.buttonStyle(.borderedProminent)
.sheet(isPresented: $showSheet) {
Textual content(“That is the resizable backside sheet.”)
.presentationDetents([.medium])
}
Spacer()
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
struct BottomSheetDemo: View {     @State personal var showSheet = false      var physique: some View {         VStack {             Button(“Present Backside Sheet”) {                 showSheet.toggle()             }             .buttonStyle(.borderedProminent)             .sheet(isPresented: $showSheet) {                 Textual content(“That is the resizable backside sheet.”)                     .presentationDetents([.medium])             }              Spacer()         }     } } |
The presentationDetents modifier accepts a set of detents for the sheet. Within the code above, we set the detent to .medium. This exhibits a backside sheet that takes up about half of the display.

To make it resizable, you need to present multiple detent for the presentationDetents modifier:
|
.presentationDetents([.medium, .large]) |
You must now see a drag bar indicating that the sheet is resizable. If you wish to conceal the drag indicator, connect the presentationDragIndicator modifier and set it to .hidden:
|
.presentationDragIndicator(.hidden) |
Apart from the preset detents akin to .medium, you possibly can create a customized detent utilizing .top and .fraction. Right here is one other instance:
|
.presentationDetents([.fraction(0.1), .medium, .large]) |
When the underside sheet first seems, it solely takes up round 10% of the display.
MultiDatePicker

The most recent model of SwiftUI comes with a brand new date picker for customers to decide on a number of dates. Beneath is the pattern code:
@State personal var selectedDates: Set<DateComponents> = []
var physique: some View {
MultiDatePicker(“Select your most well-liked dates”, choice: $selectedDates)
.body(top: 300)
}
}
|
struct MultiDatePickerDemo: View { Â Â Â Â Â @State personal var selectedDates: Set<DateComponents> = [] Â Â Â Â Â var physique: some View { Â Â Â Â Â Â Â Â MultiDatePicker(“Select your most well-liked dates”, choice: $selectedDates) Â Â Â Â Â Â Â Â Â Â Â Â .body(top: 300) Â Â Â Â } } |
NavigationStack and NavigationSplitView
NavigationView is deprecated in iOS 16. As a substitute, it’s changed by the brand new NavigationStack and NavigationSplitView. Previous to iOS 16, you utilize NavigationView to create a navigation-based interface:
.navigationTitle(“Navigation Demo”)
}
|
NavigationView {     Record {         ForEach(1...10, id: .self) { index in             NavigationLink(vacation spot: Textual content(“Merchandise #(index) element”)) {                 Textual content(“Merchandise #(index)“)             }         }     }     .listStyle(.plain)      .navigationTitle(“Navigation Demo”) } |
By pair it with NavigationLink, you possibly can create a push and pop navigation.

Since NavigationView is deprecated, iOS 16 offers a brand new view referred to as NavigationStack. This new view permits builders to create the identical sort of navigation-based UIs. Right here is an instance:
.navigationTitle(“Navigation Demo”)
}
|
NavigationStack {     Record {         ForEach(1...10, id: .self) { index in             NavigationLink {                 Textual content(“Merchandise #(index) Element”)             } label: {                 Textual content(“Merchandise #(index)“)             }         }     }     .listStyle(.plain)      .navigationTitle(“Navigation Demo”) } |
The code is similar to the previous method, besides that you just use NavigationStack as an alternative of NavigationView. So, what’s the enhancement of NavigationStack?
Let’s take a look at one other instance:
NavigationLink(worth: Shade.purple) {
Textual content(“Purple shade”)
}
}
.listStyle(.plain)
.navigationTitle(“Navigation Demo”)
.navigationDestination(for: Shade.self) { merchandise in
merchandise.clipShape(Circle())
}
.navigationDestination(for: String.self) { merchandise in
Textual content(“That is the element view for (merchandise)”)
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
NavigationStack {     Record {         NavigationLink(worth: “Textual content Merchandise”) {             Textual content(“Textual content Merchandise”)         }          NavigationLink(worth: Shade.purple) {             Textual content(“Purple shade”)         }     }     .listStyle(.plain)      .navigationTitle(“Navigation Demo”)     .navigationDestination(for: Shade.self) { merchandise in         merchandise.clipShape(Circle())     }     .navigationDestination(for: String.self) { merchandise in         Textual content(“That is the element view for (merchandise)“)     } } |
The record above is simplified with solely two rows: Textual content merchandise and Purple shade. Nonetheless, the underlying sort of those two rows usually are not the identical. One is a textual content merchandise and the opposite is definitely a Shade object.
In iOS 16, the NavigationLink view is additional improved. As a substitute of specifying the vacation spot view, it will possibly take a price that represents the vacation spot. When this pairs with the brand new navigationDestination modifier, you possibly can simply management the vacation spot view. Within the code above, now we have two navigationDestination modifiers: one for the textual content merchandise and the opposite is for the colour object.
When a consumer selects a specific merchandise within the navigation stack, SwiftUI checks the merchandise sort of the worth of the navigation hyperlink. It then calls up the vacation spot view which associates with that particular merchandise sort.

That is how the brand new NavigationStack works. That stated, it’s only a fast overview of the brand new NavigationStack. With the brand new navigationDestination modifier, you possibly can programmatically management the navigation. Say, you possibly can create a button so that you can leap on to the principle view from any element views of the navigation stack. We could have one other tutorial for that.
ShareLink for Information Sharing
iOS 16 introduces the ShareLink management for SwiftUI, permitting builders to current a share sheet. It’s very simple to make use of ShareLink. Right here is an instance:
var physique: some View {
ShareLink(merchandise: url)
}
}
|
struct ShareLinkDemo: View { Â Â Â Â personal let url = URL(string: “https://www.appcoda.com”)! Â Â Â Â Â var physique: some View { Â Â Â Â Â Â Â Â ShareLink(merchandise: url) Â Â Â Â } } |
Mainly, you present the ShareLink management with the merchandise to share. This presents a default share button. When tapped, the app exhibits a share sheet.

You’ll be able to customise the share button by offering your individual textual content and picture like this:
|
ShareLink(merchandise: url) { Â Â Â Â Label(“Share”, systemImage: “hyperlink.icloud”) } |
To manage the scale of the share sheet, you possibly can connect the presentationDetents modifier:
|
ShareLink(merchandise: url) { Â Â Â Â Label(“Share”, systemImage: “hyperlink.icloud”) } .presentationDetents([.medium, .large]) |
Desk for iPadOS
A brand new Desk container is launched for iPadOS that makes it simpler to current knowledge in tabular type. Here’s a pattern code which exhibits a desk with 3 columns:
personal let members: [Staff] = [
.init(name: “Vanessa Ramos”, position: “Software Engineer”, phone: “2349-233-323”),
.init(name: “Margarita Vicente”, position: “Senior Software Engineer”, phone: “2332-333-423”),
.init(name: “Yara Hale”, position: “Development Manager”, phone: “2532-293-623”),
.init(name: “Carlo Tyson”, position: “Business Analyst”, phone: “2399-633-899”),
.init(name: “Ashwin Denton”, position: “Software Engineer”, phone: “2741-333-623”)
]
var physique: some View {
Desk(members) {
TableColumn(“Identify”, worth: .title)
TableColumn(“Place”, worth: .place)
TableColumn(“Cellphone”, worth: .cellphone)
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
struct TableViewDemo: View { Â Â Â Â Â personal let members: [Staff] = [ Â Â Â Â Â Â Â Â .init(name: “Vanessa Ramos”, position: “Software Engineer”, phone: “2349-233-323”), Â Â Â Â Â Â Â Â .init(name: “Margarita Vicente”, position: “Senior Software Engineer”, phone: “2332-333-423”), Â Â Â Â Â Â Â Â .init(name: “Yara Hale”, position: “Development Manager”, phone: “2532-293-623”), Â Â Â Â Â Â Â Â .init(name: “Carlo Tyson”, position: “Business Analyst”, phone: “2399-633-899”), Â Â Â Â Â Â Â Â .init(name: “Ashwin Denton”, position: “Software Engineer”, phone: “2741-333-623”) Â Â Â Â ] Â Â Â Â Â var physique: some View { Â Â Â Â Â Â Â Â Desk(members) { Â Â Â Â Â Â Â Â Â Â Â Â TableColumn(“Identify”, worth: .title) Â Â Â Â Â Â Â Â Â Â Â Â TableColumn(“Place”, worth: .place) Â Â Â Â Â Â Â Â Â Â Â Â TableColumn(“Cellphone”, worth: .cellphone) Â Â Â Â Â Â Â Â } Â Â Â Â } } |
You’ll be able to create a Desk from a group of information (e.g. an array of Employees). For every column, you utilize TableColumn to specify the column title and values.

Desk works nice on iPadOS and macOS. The identical desk may be routinely rendered on iOS however solely the primary column is displayed.
Expandable Textual content Subject
TextField on iOS 16 is tremendously improved. Now you can use the axis parameter to inform iOS whether or not the textual content area needs to be expanded. Right here is an instance:
|
Kind { Â Â Â Â Part(“Remark”) { Â Â Â Â Â Â Â Â TextField(“Please sort your suggestions right here”, textual content: $inputText, axis: .vertical) Â Â Â Â Â Â Â Â Â Â Â Â .lineLimit(5) Â Â Â Â } } |
The lineLimit modifier specifies the utmost variety of strains allowed. The code above initially renders a single-line textual content area. As you sort, it routinely expands however limits its measurement to five strains.

You’ll be able to change the preliminary measurement of the textual content area by specifying a variety within the lineLimit modifier like this:
|
Kind { Â Â Â Â Part(“Remark”) { Â Â Â Â Â Â Â Â TextField(“Please sort your suggestions right here”, textual content: $inputText, axis: .vertical) Â Â Â Â Â Â Â Â Â Â Â Â .lineLimit(3...5) Â Â Â Â } } |
On this case, iOS shows a textual content area shows a three-line textual content area by default.

Gauge
SwiftUI introduces a brand new view referred to as Gauge for displaying progress. The best manner to make use of Gauge is like this:
var physique: some View {
Gauge(worth: progress) {
Textual content(“Add Standing”)
}
}
}
|
struct GaugeViewDemo: View { Â Â Â Â @State personal var progress = 0.5 Â Â Â Â Â var physique: some View { Â Â Â Â Â Â Â Â Gauge(worth: progress) { Â Â Â Â Â Â Â Â Â Â Â Â Textual content(“Add Standing”) Â Â Â Â Â Â Â Â } Â Â Â Â } } |
In essentially the most fundamental type, a gauge has a default vary from 0 to 1. If we set the worth parameter to 0.5, SwiftUI renders a progress bar indicating the duty is 50% full.

Optionally, you possibly can present labels for the present, minimal, and most values:
|
Gauge(worth: progress) { Â Â Â Â Textual content(“Add Standing”) } currentValueLabel: { Â Â Â Â Textual content(progress.formatted(.p.c)) } minimumValueLabel: { Â Â Â Â Textual content(0.formatted(.p.c)) } maximumValueLabel: { Â Â Â Â Textual content(100.formatted(.p.c)) } |
As a substitute of utilizing the default vary, you can even specify a customized vary like this:
|
Gauge(worth: progress, in: 0...100) { Â Â . Â Â . Â Â . } |
The Gauge view offers various types so that you can customise. Apart from the linear model as proven within the determine above, you possibly can connect the gaugeStyle modifier to customise the model:

ViewThatFits
ViewThatFits is a superb addition to SwiftUI permitting builders to create extra versatile UI layouts. This can be a particular sort of view that evaluates the obtainable house and presents essentially the most appropriate view on display.
Right here is an instance. We use ViewThatFits to outline two attainable layouts of the button group:
Button(motion: {}) {
Textual content(“Cancel”)
.body(maxWidth: .infinity)
.padding()
}
.tint(.grey)
.buttonStyle(.borderedProminent)
.padding(.horizontal)
}
.body(maxHeight: 200)
HStack {
Button(motion: {}) {
Textual content(“Purchase”)
.body(maxWidth: .infinity)
.padding()
}
.buttonStyle(.borderedProminent)
.padding(.main)
Button(motion: {}) {
Textual content(“Cancel”)
.body(maxWidth: .infinity)
.padding()
}
.tint(.grey)
.buttonStyle(.borderedProminent)
.padding(.trailing)
}
.body(maxHeight: 100)
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
struct ButtonGroupView: View { Â Â Â Â var physique: some View { Â Â Â Â Â Â Â Â ViewThatFits { Â Â Â Â Â Â Â Â Â Â Â Â VStack { Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Button(motion: {}) { Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Textual content(“Purchase”) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .body(maxWidth: .infinity) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .padding() Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â } Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .buttonStyle(.borderedProminent) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .padding(.horizontal) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Button(motion: {}) { Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Textual content(“Cancel”) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .body(maxWidth: .infinity) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .padding() Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â } Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .tint(.grey) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .buttonStyle(.borderedProminent) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .padding(.horizontal) Â Â Â Â Â Â Â Â Â Â Â Â } Â Â Â Â Â Â Â Â Â Â Â Â .body(maxHeight: 200) Â Â Â Â Â Â Â Â Â Â Â Â Â Â HStack { Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Button(motion: {}) { Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Textual content(“Purchase”) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .body(maxWidth: .infinity) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .padding() Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â } Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .buttonStyle(.borderedProminent) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .padding(.main) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Button(motion: {}) { Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Textual content(“Cancel”) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .body(maxWidth: .infinity) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .padding() Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â } Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .tint(.grey) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .buttonStyle(.borderedProminent) Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â .padding(.trailing) Â Â Â Â Â Â Â Â Â Â Â Â } Â Â Â Â Â Â Â Â Â Â Â Â .body(maxHeight: 100) Â Â Â Â Â Â Â Â Â } Â Â Â Â } } |
One group of the buttons is aligned vertically utilizing the VStack view. The opposite group of buttons is aligned horizontally. The maxHeight of the vertical group is ready to 200, whereas that of the horizontal group is ready to 100.
What ViewThatFits does is that it evaluates the peak of the given house and presents the most effective match view on display. Say, you set the body top to 100 like this:
|
ButtonGroupView() Â Â Â Â .body(top: 100) |
ViewThatFits determines that it’s finest to current the horizontally-aligned button group. Let’s say, you modify the body’s top to 150. The ViewThatFits view presents the vertical button group.

Gradient and Shadow

The brand new model of SwiftUI enables you to simply add linear gradient. Merely add the gradient modifier to Shade and SwiftUI routinely generates the gradients. Right here is an instance:
|
Picture(systemName: “trash”) Â Â Â Â .body(width: 100, top: 100) Â Â Â Â .background(in: Rectangle()) Â Â Â Â .backgroundStyle(.purple.gradient) Â Â Â Â .foregroundStyle(.white.shadow(.drop(radius: 1, y: 3.0))) Â Â Â Â .font(.system(measurement: 50)) |
You may as well use the shadow modifier to use shadow impact. Right here is the road of code for including a drop shadow model:
|
.foregroundStyle(.white.shadow(.drop(radius: 1, y: 3.0))) |
Grid API
SwiftUI 4.0 introduces a brand new Grid API for composing grid-based structure. You’ll be able to organize the identical structure through the use of VStack and HStact. The Grid view, nevertheless, makes it rather a lot simpler.

To create a 2×2 grid, you possibly can write the code like this:
GridRow {
IconView(systemName: “trash”)
IconView(systemName: “trash”)
}
}
|
Grid { Â Â Â Â GridRow { Â Â Â Â Â Â Â Â IconView(systemName: “trash”) Â Â Â Â Â Â Â Â IconView(systemName: “trash”) Â Â Â Â } Â Â Â Â Â GridRow { Â Â Â Â Â Â Â Â IconView(systemName: “trash”) Â Â Â Â Â Â Â Â IconView(systemName: “trash”) Â Â Â Â } } |
Contained in the Grid view, it’s a group of GridRow that embeds the grid cells.

Let’s say, the second row presents a single icon view and also you need it to span throughout two columns. You’ll be able to connect the gridCellColumns modifier and set the worth to 2:
GridRow {
IconView(systemName: “trash”)
.gridCellColumns(2)
}
}
|
Grid { Â Â Â Â GridRow { Â Â Â Â Â Â Â Â IconView(systemName: “trash”) Â Â Â Â Â Â Â Â IconView(systemName: “trash”) Â Â Â Â } Â Â Â Â Â GridRow { Â Â Â Â Â Â Â Â IconView(systemName: “trash”) Â Â Â Â Â Â Â Â Â Â Â Â .gridCellColumns(2) Â Â Â Â } } |
The Grid view may be nested to compose extra complicated layouts just like the one displayed beneath:

AnyLayout and Structure Protocol
The brand new model of SwiftUI offers AnyLayout and the Structure protocol for builders to create personalized and sophisticated layouts. AnyLayout is a type-erased occasion of the structure protocol. You should utilize AnyLayout to create a dynamic structure that responds to customers’ interactions or setting adjustments.
As an example, your app initially arranges two photographs vertically utilizing VStack. When a consumer faucets the stack view, it adjustments to a horizontal stack. With AnyLayout, you possibly can implement the structure like this:
@State personal var changeLayout = false
var physique: some View {
let structure = changeLayout ? AnyLayout(HStack(spacing: 0)) : AnyLayout(VStack(spacing: 0))
structure {
Picture(“macbook-1”)
.resizable()
.scaledToFill()
.body(maxWidth: 300, maxHeight: 200)
.clipped()
Picture(“macbook-2”)
.resizable()
.scaledToFill()
.body(maxWidth: 300, maxHeight: 200)
.clipped()
}
.animation(.default, worth: changeLayout)
.onTapGesture {
changeLayout.toggle()
}
}
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
struct AnyLayoutDemo: View {      @State personal var changeLayout = false      var physique: some View {         let structure = changeLayout ? AnyLayout(HStack(spacing: 0)) : AnyLayout(VStack(spacing: 0))           structure {             Picture(“macbook-1”)                 .resizable()                 .scaledToFill()                 .body(maxWidth: 300, maxHeight: 200)                 .clipped()              Picture(“macbook-2”)                 .resizable()                 .scaledToFill()                 .body(maxWidth: 300, maxHeight: 200)                 .clipped()          }         .animation(.default, worth: changeLayout)         .onTapGesture {             changeLayout.toggle()         }      } } |
We will outline a structure variable to carry an occasion of AnyLayout. Relying on the worth of changeLayout, this structure adjustments between horizontal and vertical layouts.
By attaching the animation to the structure, the structure change will likely be animated.

The demo lets customers change the structure by tapping the stack view. In some functions, chances are you’ll need to change the structure based mostly on the gadget’s orientation and display measurement. On this case, you possibly can seize the orientation change through the use of the .horizontalSizeClass variable:
|
@Atmosphere(.horizontalSizeClass) var horizontalSizeClass |
And then you definitely replace the structure variable like this:
|
let structure = horizontalSizeClass == .common ? AnyLayout(HStack(spacing: 0)) : AnyLayout(VStack(spacing: 0)) |
Say, for instance, you rotate an iPhone 13 Professional Max to panorama, the structure adjustments to horizontally stack view.

Typically, we use SwiftUI’s built-in structure containers like HStack and VStack to compose layouts. What if these structure containers usually are not ok for arranging the kind of layouts you want? The Structure protocol launched in iOS 16 permits you to outline your individual customized structure. This can be a extra complicated subject, so we’ll talk about this new protocol in one other tutorial.
Abstract
This 12 months, Apple as soon as once more delivered tons of nice options for the SwiftUI framework. The Charts API, the revamp of navigation view, and the introduction of AnyLayout will certainly enable you construct extra elegant and interesting UIs. I’m nonetheless exploring the brand new APIs of SwiftUI. If I miss any nice updates, please do depart a remark beneath and let me know.
Word: We’re updating our Mastering SwiftUI guide for iOS 16. If you wish to begin studying SwiftUI, take a look at the guide right here. You’ll obtain a free replace later this 12 months.
[ad_2]
