👔StackForEach
⬆️ 需要:📦 ScrollHStackForEach, 📦 ScrollVStackForEach
struct ContentView: View {
    var body: some View {
        HStack {
            Group {
                // 📦 ScrollHStackForEach
                ScrollHStackForEach(0..<60) { numberBall($0) }
                // 📦 ScrollVStackForEach
                ScrollVStackForEach(0..<30) { numberBall($0) }
                    .frame(height: 400)
            }
            .border(Color.yellow)      // scroll view border (yellow)
            .padding()
            .background(Color.gray4)
            .border(Color.pink)        // padding border (pink)
            .padding()
        }
    }
}
extension ContentView {
    /// number in a circle
    func numberBall(_ i: Int) -> some View {
        ZStack {
            Circle()
                .fill(Color.purple)
                .frame(width: 60, height: 60)
            Text("\(i)")
        }
        .font(.largeTitle)
        .shadow(radius: 4)
    }
}// 2020.10.15 - (first version) HStackForEach, VStackForEach
// 2022.01.20 + ScrollHStackForEach, ScrollVStackForEach
//
// #todo: ZStackForEach ?
import SwiftUI
// ------------------------
//     📦 HStackForEach
// ------------------------
public struct HStackForEach<Content: View>: View  {
    
    // properties
    let data     : Range<Int>
    let alignment: VerticalAlignment
    let spacing  : CGFloat?
    let content  : (Int) -> Content
    
    // body
    public var body: some View {
        HStack(alignment: alignment, spacing: spacing) {
            ForEach(data) { i in self.content(i) }
        }
    }
}
// extension
extension HStackForEach {
    public init(
        _ data   : Range<Int>, 
        alignment: VerticalAlignment = .center,
        spacing  : CGFloat?          = nil,
        content  : @escaping (Int) -> Content
    ) {
        self.data      = data
        self.alignment = alignment
        self.spacing   = spacing
        self.content   = content
    }
}
// ------------------------------
//     📦 ScrollHStackForEach
// ------------------------------
public struct ScrollHStackForEach<Content: View>: View {
    // properties
    let data     : Range<Int>
    let alignment: VerticalAlignment
    let spacing  : CGFloat?
    let content  : (Int) -> Content
    // view body
    public var body: some View {
        ScrollView(.horizontal){
            HStackForEach(data, alignment: alignment, spacing: spacing, content: content)
        }
    }
}
// extension
extension ScrollHStackForEach {
    public init(
        _ data   : Range<Int>, 
        alignment: VerticalAlignment = .center,
        spacing  : CGFloat?          = nil,
        content  : @escaping (Int) -> Content
    ) {
        self.data      = data
        self.alignment = alignment
        self.spacing   = spacing
        self.content   = content
    }
}
// ------------------------
//     📦 VStackForEach
// ------------------------
// 📦 VStackForEach
public struct VStackForEach<Content: View>: View  {
    
    // properties
    let data     : Range<Int>
    let alignment: HorizontalAlignment
    let spacing  : CGFloat?
    let content  : (Int) -> Content
    
    // body
    public var body: some View {
        VStack(alignment: alignment, spacing: spacing) {
            ForEach(data) { i in self.content(i) }
        }
    }
}
extension VStackForEach {
    public init(
        _ data   : Range<Int>, 
        alignment: HorizontalAlignment = .center,
        spacing  : CGFloat?            = nil,
        content  : @escaping (Int) -> Content
    ) {
        self.data      = data
        self.alignment = alignment
        self.spacing   = spacing
        self.content   = content
    }
}
// ------------------------------
//     📦 ScrollVStackForEach
// ------------------------------
public struct ScrollVStackForEach<Content: View>: View {
    // properties
    let data     : Range<Int>
    let alignment: HorizontalAlignment
    let spacing  : CGFloat?
    let content  : (Int) -> Content
    // view body
    public var body: some View {
        ScrollView(.vertical){
            VStackForEach(data, alignment: alignment, spacing: spacing, content: content)
        }
    }
}
// extension
extension ScrollVStackForEach {
    public init(
        _ data   : Range<Int>, 
        alignment: HorizontalAlignment = .center,
        spacing  : CGFloat?          = nil,
        content  : @escaping (Int) -> Content
    ) {
        self.data      = data
        self.alignment = alignment
        self.spacing   = spacing
        self.content   = content
    }
}
Last updated
Was this helpful?