swiftuiswiftui-layout

Adding Fixed/Scrollable Space Between Two Icons


I am looking to create a SwiftUI layout that has one icon to the far left, two icons to the far right, and a fixed-width scrollable area for any number of icons in between:

goal layout

The issue I'm running into is that the scrollable area overlaps the icons on the right, and does not actually scroll:

actual layout

Without hard-coding numbers into my layout, how can I achieve this?


let rows: [GridItem] = [GridItem()]
HStack(spacing: 0) {
    LazyHGrid(rows: rows, alignment: .top, spacing: 0) {
        FilterButton(
            icon: "house",
            text: "All",
            width: 32,
            height: 32,
            foregroundColor: .white,
            backgroundColor: .accentColor
        ) {

        }

        ScrollView(.horizontal) {
            ForEach (members, id: \.id) { member in
                HStack {
                    FilterButton(
                        icon: member.imageName ?? "person",
                        text: member.name,
                        width: 32,
                        height: 32,
                        foregroundColor: .white,
                        backgroundColor: .accentColor,
                        alignment: .leading
                    ) {

                    }
                }
            }
        }
    }
    .frame(maxWidth: 0, alignment: .leading)

    LazyHGrid(rows: rows, alignment: .top, spacing: 0) {
        FilterButton(
            icon: "line.3.horizontal.decrease.circle",
            text: "Filter",
            width: 32,
            height: 32,
            foregroundColor: .accentColor
        ) {

        }

        FilterButton(
            icon: "text.line.first.and.arrowtriangle.forward",
            text: "Sort",
            width: 32,
            height: 32,
            foregroundColor: .accentColor,
            overlay: false
        ) {

        }
    }
    .frame(maxWidth: .infinity, alignment: .trailing)
}


Solution

  • We can simply use Hstack. Here LazyHGrids are not necessary, Because you only have maximum two items in a lazy grid.

    struct ContentView: View {
        var body: some View {
            HStack {
                Rectangle()
                    .frame(width: 32, height: 32)
                
                ScrollView(.horizontal) { 
                    HStack {
                        ForEach(0 ..< 50) { item in
                            Circle()
                                .frame(width: 32, height: 32)
                        }
                    }
                }
                
                Rectangle()
                    .frame(width: 32, height: 32)
                Rectangle()
                    .frame(width: 32, height: 32)
                
            }
        }
    }
    

    enter image description here