๐AdaptiveHStack
Last updated
Last updated
SwiftUI โฉ Layout โฉ Adaptive Layout โฉ Size Classes โฉ
โฌ๏ธ ้่ฆ๏ผ ๐ AdaptiveHStack
struct ContentView: View {
@State private var isCompact = true
let text = """
For simplicity's sake, we will focus on conditions based on the horizontal space available: the same concepts can also be applied for vertical space.
"""
var body: some View {
Toggle("is compact", isOn: $isCompact)
.padding()
Spacer()
// ๐ AdaptiveHStack
AdaptiveHStack(threshold: isCompact, alignment: .top) {
// RoundedRectangle
RoundedRectangle(cornerRadius: 16)
.fill(Color.pink)
.frame(maxHeight: 300)
// VStack
VStack {
Text("Title")
.bold()
.font(.title)
Text(text)
.fixedSize(horizontal: false, vertical: true)
}
}
}
}
็ถ AdaptiveHStack ็ๅฏฌๅบฆๅฐๆผ่จญๅฎ็็็ทๆ๏ผๅฐฑๆ่ฝ่ฎ็บ VStackใ
โฌ๏ธ ้่ฆ๏ผ ๐ AdaptiveHStack
struct ContentView: View {
@State var width: CGFloat = 400
@State var threshold: CGFloat = 300
var tooNarrow: Bool {
width < threshold
}
var body: some View {
VStack {
// ๐ AdaptiveHStack
AdaptiveHStack(threshold: tooNarrow, spacing: 0) {
Rectangle().fill(Color.red)
Rectangle().fill(Color.green)
}
.frame(width: width) // width
.overlay(
Rectangle()
.stroke(lineWidth: 2)
.frame(width: threshold) // threshold
)
Form {
HStack {
Text("width: \(Int(width))")
Slider(value: $width, in: 0...500, step: 10)
}
HStack {
Text("threshold: \(Int(threshold))")
Slider(value: $threshold, in: 0...500, step: 10)
}
}
}
.padding()
}
}
import SwiftUI
/// โญ AdaptiveHStack
/// `HStack` which transforms into `VStack` when `threshold` is met.
/// - usage: `AdaptiveHStack(threshold: condition) { ... }`
public struct AdaptiveHStack<Content: View>: View {
let threshold: () -> Bool
let alignment: Alignment
let spacing : CGFloat?
let content : () -> Content
public var body: some View {
if threshold() {
VStack(
alignment: alignment.horizontal,
spacing: spacing,
content: content)
} else {
HStack(
alignment: alignment.vertical,
spacing: spacing,
content: content)
}
}
}
/// convenient init
extension AdaptiveHStack {
public init(
threshold: @autoclosure @escaping () -> Bool,
alignment: Alignment = .center,
spacing : CGFloat? = nil,
@ViewBuilder content: @escaping () -> Content
) {
self.alignment = alignment
self.spacing = spacing
self.content = content
self.threshold = threshold
}
}