You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS15下SwiftUI实现带“Replaces”行的不规则LazyVGrid布局问题

SwiftUI LazyVGrid 添加“Replaces”行实现方案

需求说明

我用SwiftUI的LazyVGrid搭建购物车商品行网格布局,目前完成了核心内容,但还需要添加一行“Replaces”文本,要求:

  • 对齐商品描述区域,放在单价文本下方
  • 占据网格剩余的全部宽度
  • 不能用H/VStack(列对齐麻烦,扩展性差)
  • 兼容iOS15及以上版本

当前代码:

let columns = [
    GridItem(.flexible()),
    GridItem(.flexible(minimum: 150), alignment: .topLeading),
    GridItem(.flexible(), alignment: .topTrailing),
    GridItem(.flexible(), alignment: .topTrailing)
]

private func refundedLine(_ line: PlacedOrderLine) -> some View {
    LazyVGrid(columns: columns) {
        itemImage(item: line.item)
        
        VStack(alignment: .leading, spacing: 4) {
            Text(viewModel.itemName(line.item))
                .font(.Body2.regular())
                            
            Text(line.item.price.pricePerItemString)
                .font(.Body2.semiBold())
        }
        
        Text("\(line.quantity)")
            .font(.Body2.semiBold())
            .foregroundColor(colorPalette.primaryRed)
        
        Text(viewModel.pricePaid(line: line))
            .font(.Body2.semiBold())
            .foregroundColor(colorPalette.primaryRed)
            .strikethrough()
    }
}

解决方案

利用LazyVGrid的跨列特性就能实现,不用额外嵌套Stack,具体修改如下:

let columns = [
    GridItem(.flexible()),
    GridItem(.flexible(minimum: 150), alignment: .topLeading),
    GridItem(.flexible(), alignment: .topTrailing),
    GridItem(.flexible(), alignment: .topTrailing)
]

private func refundedLine(_ line: PlacedOrderLine) -> some View {
    LazyVGrid(columns: columns, spacing: 16) {
        // 商品图片,保持顶部对齐
        itemImage(item: line.item)
            .gridCellAnchor(.top)
        
        // 商品名称+单价区域
        VStack(alignment: .leading, spacing: 4) {
            Text(viewModel.itemName(line.item))
                .font(.Body2.regular())
            
            Text(line.item.price.pricePerItemString)
                .font(.Body2.semiBold())
        }
        
        // 数量文本,顶部对齐
        Text("\(line.quantity)")
            .font(.Body2.semiBold())
            .foregroundColor(colorPalette.primaryRed)
            .gridCellAnchor(.top)
        
        // 总价文本,顶部对齐
        Text(viewModel.pricePaid(line: line))
            .font(.Body2.semiBold())
            .foregroundColor(colorPalette.primaryRed)
            .strikethrough()
            .gridCellAnchor(.top)
        
        // 添加Replaces行:跨越3列(从第二列到第四列),左对齐商品描述
        Text("Replaces \(viewModel.replacedItemName(line))") // 替换为实际数据
            .font(.Body2.regular()) // 可根据需求调整字体样式
            .foregroundColor(colorPalette.secondaryText)
            .gridCellColumns(3)
            .gridCellAnchor(.leading)
    }
}

关键说明

  • gridCellColumns(3):让“Replaces”文本跨越3列,刚好覆盖商品描述、数量、总价的列空间,实现“占据剩余宽度”的要求。
  • gridCellAnchor(.leading):确保文本和商品描述左对齐,符合布局预期。
  • gridCellAnchor(.top):给图片、数量、总价添加顶部锚点,保证整行元素顶部对齐,避免布局偏移。
  • 该方案完全基于LazyVGrid实现,没有嵌套额外的H/VStack,扩展性强,且所有API在iOS15及以上版本都支持,满足兼容性要求。

内容的提问来源于stack exchange,提问作者DevB1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 10:50:22