LazyVGrid 行居中对齐

问题描述 投票:0回答:1

我正在创建一个包含 2 列的 LazyVGrid。我想要这样,如果一行中只有一个项目,那么它会转到该行的中心。我尝试将 HStack 与 Spacer 一起使用,但它不会将其推到中心。有谁知道怎么做吗?

LazyVGrid(columns: columns, alignment: .center, spacing: 35) {
                ForEach(pets) { pet in
                    VStack {
                        Image(pet.species.rawValue)
                            .resizable()
                            .frame(width: 80, height: 80)
                        
                        Text(pet.name)
                            .poppinsBold(size: 16)
                    }
                }
                
                HStack {
    
                    if pets.hasEvenNumber {
                        Spacer(minLength: 0)
                    }
    
                    Button {
                        addPetSheet = true
                    } label: {
                        VStack {
                            ZStack {
                                Circle()
                                    .frame(width: 70, height: 70)
                                    .foregroundStyle(.gray)
                                
                                Image(systemName: "plus")
                                    .foregroundStyle(.white)
                                    .font(.title)
                            }
                            
                            Text("Add")
                                .poppinsBold(size: 16)
                        }
                    }
                }
                
            }
swift swiftui
1个回答
0
投票

如果某个东西可以位于 2 列网格的中心,它就不再是网格

当宠物数量为偶数时,应将添加按钮放在

LazyVGrid
之外。确保
LazyVStack
的父级居中对齐。

LazyVGrid(...) {
    ForEach(pets) { pet in
        ...
    }
    if !pets.count.isMultiple(of: 2) {
        AddButton(...)
    }
}
if pets.count.isMultiple(of: 2) {
    AddButton(...)
}

这是一个更完整的示例 - 我在两个添加按钮上添加了匹配的几何效果,因此动画看起来很自然。

struct Pet: Identifiable, Hashable {
    let name: String
    let image: String
    var id: String { name }
}

struct ContentView: View {
    @State var pets = [
        Pet(name: "Foo", image: "cat"),
        Pet(name: "Bar", image: "dog"),
        Pet(name: "Baz", image: "bird"),
        Pet(name: "Goo", image: "cat"),
        Pet(name: "Gar", image: "dog"),
        Pet(name: "Boo", image: "bird"),
        Pet(name: "Last", image: "cat"),
    ]
    
    @Namespace var ns
    
    var body: some View {
        ScrollView(.vertical) {
            LazyVGrid(columns: [.init(.fixed(80)), .init(.fixed(80))]) {
                ForEach(pets) { pet in
                    VStack {
                        Image(systemName: pet.image)
                            .resizable()
                            .frame(width: 80, height: 80)
                        Text(pet.name)
                    }
                }
                if !pets.count.isMultiple(of: 2) {
                    addButton
                        .matchedGeometryEffect(id: "add", in: ns)
                }
            }
            if pets.count.isMultiple(of: 2) {
                addButton
                    .matchedGeometryEffect(id: "add", in: ns)
            }
        }
    }
    
    @ViewBuilder
    var addButton: some View {
        AddButton {
            withAnimation {
                pets.append(Pet(name: "New", image: "dog"))
            }
        }
    }
}

struct AddButton: View {
    let action: () -> Void
    var body: some View {
        Button(action: action) {
            VStack {
                ZStack {
                    Circle()
                        .frame(width: 70, height: 70)
                        .foregroundStyle(.gray)
                    
                    Image(systemName: "plus")
                        .foregroundStyle(.white)
                        .font(.title)
                }
                
                Text("Add")
            }
        }
    }
}

如果您的网格有更多列,请考虑使用自定义

Layout
。例如,
HFlow
horizontalAlignment: .center

© www.soinside.com 2019 - 2024. All rights reserved.