SwiftUI LazyVGrid 内容压缩

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

我正在尝试构建一个网格,由其下带有图像和文本的项目组成。 我希望所有图像都具有相同的大小,并且文本可以根据文本的需要扩展单元格的高度。但图像总是被压缩以保持所有单元格高度相等并且文本不被截断。

我已经为 LazyVGrid 尝试了很多修改器,并为 GridItem 设置了大小参数,但仍然没有达到预期的结果

我应该如何构建所描述的 UI?我应该使用LazyVGrid还是使用Grid更好(内容是静态的并且项目数量相对较小要考虑优化)?

    let layout = [
        GridItem(),
        GridItem(),
        GridItem()
    ]
    
    var body: some View {
        ScrollView {
            LazyVGrid(columns: layout, spacing: 10) {
                ForEach(cardsContainer.cards) { card in
                    VStack {
                        if let uiImage = UIImage(named: card.imageName) {
                            Image(uiImage: uiImage)
                                .resizable()
                                .scaledToFill()
                                .clipped()
                        }
                        Text(card.name)
                        Text(card.arcana.rawValue)
                    }
                }
            }
        }
    }

PS 可能 smbdy 可以建议一些关于使用 SwiftUI 构建集合的高级方面的好资源,因为我只找到了有关它的基本信息,并且只找到了一些关于 SwiftUI 中的网格与堆栈比较的信息。

swift swiftui layout grid lazyvgrid
1个回答
0
投票

看起来卡片的名称需要限制在一行。您可以通过将

.lineLimit(1)
应用于文本来完成此操作。

为了避免截断(带有省略号),您可以使用

.minimumScaleFactor
来缩小字体。但是,当您这样做时,这意味着某些标签将比其他标签小,因此卡片的高度将不再完全相同。

解决此问题的方法是建立标准标签所需的占地面积,然后将实际标签显示为覆盖层。像这样:

VStack {
    if let uiImage = UIImage(named: card.imageName) {
        Image(uiImage: uiImage)
            .resizable()
            .scaledToFill()
            .clipped()
    }
    VStack {
        Text(card.name)
        Text(card.arcana.rawValue)
    }
    .lineLimit(1)
    .hidden() // Hide the footprint
    .overlay {
        VStack {
            Text(card.name)
            Text(card.arcana.rawValue)
        }
        .lineLimit(1)
        .minimumScaleFactor(0.5)
    }
}

Screenshot

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