“This is the fifth day of my participation in the First Challenge 2022. For details: First Challenge 2022”
Use Size Class to create different layouts
SwiftUI uses Size Class to create different layouts. To use them, first create an @Environment object that will store its value, then examine the value of that property as needed, looking for.compact or.regular size classes.
struct ContentView: View {
@Environment(.horizontalSizeClass) var horizontalSizeClass
var body: some View {
if horizontalSizeClass = = .compact {
Text("Compact")}else {
Text("Regular")}}}Copy the code
Size Class is a great way to make your user interface intelligently fit the available space by using VStack or HStack for your content. For example, if you have a lot of space, you might place things horizontally, but switch to a vertical layout when space is limited.
Use Size Class to automatically switch between Vstack and HStack
SwiftUI can monitor the current size class to determine how it should be arranged, such as switching from HStack when there is plenty of space to VStack when space is limited.
A new AdaptiveStack view can be written that will automatically switch between horizontal and vertical layouts for us. This makes it much easier to create great layouts on the iPad,
struct AdaptiveStack<Content: View> :View {
@Environment(\.horizontalSizeClass) var sizeClass
let horizontalAlignment: HorizontalAlignment
let verticalAlignment: VerticalAlignment
let spacing: CGFloat?
let content: () -> Content
init(horizontalAlignment: HorizontalAlignment = .center, verticalAlignment: VerticalAlignment = .center, spacing: CGFloat? = nil.@ViewBuilder content: @escaping() - >Content) {
self.horizontalAlignment = horizontalAlignment
self.verticalAlignment = verticalAlignment
self.spacing = spacing
self.content = content
}
var body: some View {
Group {
if sizeClass = = .compact {
VStack(alignment: horizontalAlignment, spacing: spacing, content: content)
} else {
HStack(alignment: verticalAlignment, spacing: spacing, content: content)
}
}
}
}
struct ContentView: View {
var body: some View {
AdaptiveStack {
Text("Horizontal when there's lots of space")
Text("but")
Text("Vertical when space is restricted")}}}Copy the code
-
First, listen on the HorizontalSizeClass in the custom View so that it will be updated every time the size class changes.
-
And it provides separate storage of horizontal and vertical alignment parameters, so you can control exactly how the layout should fit.
-
There is an optional CGFloat value for spacing, because that’s how VStack and HStack work. If you want more control, you can add the HorizontalSpacing and verticalSpacing attributes.
-
The Content property is a function that takes no arguments and returns something that will eventually be relied on to create their layout.
-
Our initializer hides them all for later use.
-
In the Body property, you can read the horizontal dimension class and wrap the call to Content () in either VStack or HStack.
Use ScrollView
SwiftUI’s ScrollView allows developers to create a scrolling container for views with relative ease, as it automatically resists itself to fit what we put in it, and also automatically adds additional illustrations to avoid safe areas.
ScrollView {
VStack(spacing: 20) {
ForEach(0..<10) {
Text("Item ($0)")
.foregroundColor(.white)
.font(.largeTitle)
.frame(width: 200, height: 200)
.background(Color.red)
}
}
}
.frame(height: 350)
Copy the code
By default, the scroll view is vertical, but you can control the axis by passing.horizontal as the first argument. Therefore, we can flip the previous example horizontally, as follows:
ScrollView(.horizontal) {
HStack(spacing: 20) {
ForEach(0..<10) {
Text("Item ($0)")
.foregroundColor(.white)
.font(.largeTitle)
.frame(width: 200, height: 200)
.background(Color.red)
}
}
}
Copy the code
You can specify two shafts simultaneously using the [. Horizontal,. Vertical].
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 20) {
ForEach(0..<10) {
Text("Item ($0)")
.foregroundColor(.white)
.font(.largeTitle)
.frame(width: 200, height: 200)
.background(Color.red)
}
}
}
Copy the code
Slide the ScrollView to the specified position
If you want to programmatically move SwiftUI’s ScrollView to a specific location, you should embed a ScrollViewReader in it. This provides a scrollTo() method that can move to any view within the parent scroll view by providing its anchor point.
For example, this creates 100 colored boxes in the vertical scroll view, and when you press the button, it scrolls directly to the box with ID 8:
struct ContentView: View {
let colors: [Color] = [.red, .green, .blue]
var body: some View {
ScrollView {
ScrollViewReader { value in
Button("Jump to #8") {
value.scrollTo(8)
}
.padding()
ForEach(0..<100) { i in
Text("Example (i)")
.font(.title)
.frame(width: 200, height: 200)
.background(colors[i % colors.count])
.id(i)
}
}
}
.frame(height: 350)}}Copy the code
For better control of scrolling, you can specify a second parameter called an anchor point to control the position of the target view after scrolling is complete.
For example, this will scroll to the same view as before, but this time put that view at the top:
struct ContentView: View {
let colors: [Color] = [.red, .green, .blue]
var body: some View {
ScrollView {
ScrollViewReader { value in
Button("Jump to #8") {
value.scrollTo(8, anchor: .top)
}
.padding()
ForEach(0..<100) { i in
Text("Example (i)")
.font(.title)
.frame(width: 200, height: 200)
.background(colors[i % colors.count])
.id(i)
}
}
}
.frame(height: 350)}}Copy the code