👔AdaptiveHStack
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
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
    }
}Last updated
Was this helpful?