近年来,Bento Grid (便当盒) 布局在设计界大放异彩。从 Apple 官网的 iPhone 宣传页,到 iOS 系统的 Widget 桌面组件,再到各种前沿的网页设计,这种网格化、卡片式的信息聚合方式都展现出了极高的视觉张力和实用性。

作为 iOS 开发者,如何高效地在 SwiftUI 中实现这种非对称、支持多跨度的网格卡片布局呢?本文将为你拆解几种实现方案。

方案一:使用 iOS 16+ 的 Grid 视图

在 iOS 16 之前,我们只能依靠 LazyVGridLazyHGrid 来排版,但它们在处理非对称的多行多列跨度时十分吃力。iOS 16 引入了 GridGridRow,这让构建 Bento Grid 变得异常简单。

struct BentoGridView: View {
    var body: some View {
        Grid(horizontalSpacing: 16, verticalSpacing: 16) {
            // 第一行:一个大卡片,占据两列
            GridRow {
                AppIntroCard()
                    .gridCellColumns(2)
                
                SmallStatCard(title: "下载量", value: "10K+")
            }
            
            // 第二行:三个等宽的小卡片
            GridRow {
                SmallFeatureCard(icon: "star.fill", text: "4.9 分")
                
                SmallFeatureCard(icon: "bolt.fill", text: "极速")
                
                SmallFeatureCard(icon: "lock.fill", text: "隐私安全")
            }
            
            // 第三行:左边小卡片,右边大卡片
            GridRow {
                SmallStatCard(title: "大小", value: "24 MB")
                
                NewsletterCard()
                    .gridCellColumns(2)
            }
        }
        .padding()
    }
}

核心 API 解析:

  • Grid:声明一个网格容器,它会同时计算行与列,强制让每一行的列宽对齐。
  • GridRow:网格中的一行。
  • .gridCellColumns(N):类似于 HTML 中的 colspan,指定该卡片横跨几列。这正是实现 Bento Grid 不规则布局的灵魂所在。

方案二:为 Apple 风格卡片添加毛玻璃 (Glassmorphism) 效果

Bento Grid 卡片的精致感很大程度上源于它的材质(Material)和光影效果。在 SwiftUI 中,我们可以结合 .background(.ultraThinMaterial) 来制作毛玻璃卡片:

struct BentoCard<Content: View>: View {
    var content: Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        content
            .padding(20)
            .background(.ultraThinMaterial)
            .cornerRadius(24)
            .shadow(color: Color.black.opacity(0.05), radius: 10, x: 0, y: 5)
            .overlay(
                RoundedRectangle(cornerRadius: 24)
                    .stroke(Color.white.opacity(0.15), lineWidth: 1)
            )
    }
}

通过加入浅色的白色描边 .stroke(Color.white.opacity(0.15), lineWidth: 1),可以在深色背景下勾勒出卡片的边缘,极大地增强了质感。

方案三:适配 iPad 和 Mac 的响应式 Bento 布局

如果你的 App 支持 iPadOS 或 macOS,单列的 Bento 布局可能会显得非常空旷。这时我们需要利用 horizontalSizeClass 或者 GeometryReader 来动态调整布局跨度。

@Environment(\.horizontalSizeClass) var sizeClass

var body: some View {
    if sizeClass == .regular {
        // iPad 宽屏版 Bento 布局 (例如 3 列或 4 列)
        WideBentoLayout()
    } else {
        // iPhone 竖屏版 Bento 布局 (收拢为单列或双列)
        CompactBentoLayout()
      }
}

总结

Bento Grid 不仅是一种新颖的设计趋势,更是一种极佳的信息架构方式。在 SwiftUI 中使用全新的 Grid API,配合系统自带的材质修饰符,只需寥寥数行代码,就能让你的 App 拥有媲美 Apple 官方设计水准的精致界面。快在你的下一个 iOS 项目中尝试一下吧!