SwiftUI如何在LazyVGrid中居中显示项目

7

我刚接触SwiftUI,并尝试在LazyVGrid视图中居中元素。

以下是当前的代码:

enter image description here

使用:

var body: some View {
    ZStack {
        Color(red: 75/255, green: 0, blue: 130/255).ignoresSafeArea()
        VStack {
            LazyVGrid(columns: [GridItem(.adaptive(minimum: 30))], alignment: .center, spacing: 10) {
                let letters = wordToArray(word: testWord)
                ForEach(Array(letters.enumerated()), id: \.offset) { letter in
                    Text(String(letter.element).capitalized)
                        .foregroundColor(.blue)
                        .frame(width:30, height: 40)
                        .background(Color.yellow)
                        .cornerRadius(5)
                }
            }
            .padding()
        }
    }
}

但是,正如您所看到的,这只会将元素左对齐 - 我也不知道需要显示多少个字符。我还希望保持它们之间的间距与上面相同。

非常感谢您的帮助!

谢谢。


VStack(alignment:.center)无效吗? - Daryl Wong
3个回答

5

两种选项

struct CenteredLVSView: View {
    @State var letters: [String] = ["A", "B", "C", "D", "E","A", "B", "C", "D", "E","A", "B", "C", "D", "E"]
    //Specify column count and it will justify/center by width
    @State var columnCount: Int = 5
    var body: some View {
        ZStack {
            Color(red: 75/255, green: 0, blue: 130/255).ignoresSafeArea()
            LazyVGrid(columns: Array(repeating: GridItem(.flexible(minimum: 30
                 //If you set max it will center on width if smaller than max, uncomment below
                 //, maximum: 40
            )), count: columnCount), spacing: 10){
                ForEach(Array(letters.enumerated()), id: \.offset) { letter in
                    Text(String(letter.element).capitalized)
                        .foregroundColor(.blue)
                        .frame(width:30, height: 40)
                        .background(Color.yellow)
                        .cornerRadius(5)
                }
            }
            .padding()
        }
    }
}

LazyVGrid - Justified

改为使用LazyHGrid

struct CenteredLVSView: View {
    @State var letters: [String] = ["A", "B", "C", "D", "E","A", "B", "C", "D", "E","A", "B", "C", "D", "E"]
    //Specify row count and it will justify/center height
    @State var rowCount: Int = 5
    var body: some View {
        ZStack {
            Color(red: 75/255, green: 0, blue: 130/255).ignoresSafeArea()
            LazyHGrid(rows: Array(repeating: GridItem(.flexible(minimum: 30
                //If you set max it will center if smaller than max, height uncomment below
                //, maximum: 40
            )), count: rowCount), spacing: 10){
                ForEach(Array(letters.enumerated()), id: \.offset) { letter in
                    Text(String(letter.element).capitalized)
                        .foregroundColor(.blue)
                        .frame(width:30, height: 40)
                        .background(Color.yellow)
                        .cornerRadius(5)
                }
            }
            .padding()
        }
    }
}

LazyHGrid - 等宽对齐

如评论中所述,如果您设置了一个maximum,它们将居中/对齐到最大值

LazyHGrid带有3行,最大值为40 LazyHGrid带有3行

LazyVGrid带有5列,最大值为40 LazyVGrid带有5列


2

我遇到了同样的问题,无法解决,所以我使用了ScrollView和foreach来实现我需要的相同方式。

struct Subview: View {
var Items = ["a","b","c","d","e"]
var body: some View {
    ZStack(){
        Color("AccentColor").edgesIgnoringSafeArea(.all)
        VStack{
            HStack(alignment:.center){
            GeometryReader { geo in
                ScrollView(.horizontal,showsIndicators: false){
                HStack(alignment:.center){
                ForEach(Items, id: \.self) { item in
                Button {
                    } label: {
                Text("\(item)")
                }.frame(width:50,height: 50, alignment: .center).background(Color.red).cornerRadius(25)
                                
                }
                            
                            
                }.frame(width:geo.size.width,height: geo.size.height ,alignment: .center)
                        }
                    }
            }.frame(width: UIScreen.main.bounds.width - 40, height: 100, alignment: .center)
        }
        
    }.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height, alignment: .center)
            
}    }

enter image description here


0
那些像我一样仍在寻找答案的人,我已经在自适应网格中找到了解决方案,就像这样:
import SwiftUI

struct ContentView: View {
    
    private let adaptiveColumn = [
        GridItem(.adaptive(minimum: 250, maximum: 350))
    ]
    var body: some View {
        
        LazyVGrid(columns: adaptiveColumn, spacing: 20) {
            
            ForEach(1..<5) { item in
                Text(String(item))
                    .frame(width: 250, height: 50)
                    .padding(20)
                    .foregroundColor(.white)
                    .background(.blue)
                    .cornerRadius(10)
            }
        }
    }
}

#Preview {
    ContentView()
}

在此输入图像描述 问题在于您必须设置最小宽度,以防止其他项目能够适应右侧。如果右侧有足够的空间容纳另一个项目,LazyVGrid将为新项目保留该空间。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接