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

如何为SwiftUI LazyVGrid实现单选状态并自定义选中样式

实现导航视图详情区域网格视图的单选功能

核心思路

通过状态变量追踪当前选中项的ID,结合点击手势切换选中状态,同时根据选中状态自定义视图样式,实现类似List的单选效果(不支持多选)。

步骤实现

1. 定义数据模型

先创建可识别的数据模型,用于承载网格项数据:

struct GridItemModel: Identifiable {
    let id = UUID()
    let title: String
    // 可按需添加图片、描述等其他属性
}

2. 构建网格视图与单选逻辑

使用LazyVGrid搭建网格,通过@State变量管理选中状态,在点击手势中处理单选切换逻辑:

struct DetailGridView: View {
    // 追踪当前选中项的ID,nil表示无选中项
    @State private var selectedItemId: UUID?
    
    // 模拟网格数据
    let gridItems: [GridItemModel] = [
        GridItemModel(title: "项目1"),
        GridItemModel(title: "项目2"),
        GridItemModel(title: "项目3"),
        GridItemModel(title: "项目4"),
        GridItemModel(title: "项目5"),
        GridItemModel(title: "项目6")
    ]
    
    // 网格列配置
    let columns = [
        GridItem(.flexible()),
        GridItem(.flexible())
    ]
    
    var body: some View {
        LazyVGrid(columns: columns, spacing: 16) {
            ForEach(gridItems) { item in
                // 自定义网格项视图,传入选中状态
                GridItemCard(item: item, isSelected: selectedItemId == item.id)
                    .onTapGesture {
                        // 切换选中状态:已选中则取消,未选中则选中当前项
                        selectedItemId = selectedItemId == item.id ? nil : item.id
                    }
            }
        }
        .padding()
    }
}

3. 自定义选中样式

创建独立的网格项视图,根据isSelected参数调整样式:

struct GridItemCard: View {
    let item: GridItemModel
    let isSelected: Bool
    
    var body: some View {
        VStack(alignment: .center, spacing: 8) {
            Text(item.title)
                .font(.subheadline)
                .fontWeight(isSelected ? .semibold : .regular)
                .foregroundColor(isSelected ? .white : .primary)
            
            // 可按需添加图片或其他内容
            // Image(systemName: "square.fill")
            //     .foregroundColor(isSelected ? .white : .secondary)
        }
        .frame(height: 140)
        .frame(maxWidth: .infinity)
        .background(isSelected ? .blue : .gray.opacity(0.15))
        .cornerRadius(12)
        .overlay(
            // 选中时添加边框效果
            RoundedRectangle(cornerRadius: 12)
                .stroke(isSelected ? .white.opacity(0.9) : .clear, lineWidth: 2)
        )
        .shadow(color: isSelected ? .blue.opacity(0.3) : .clear, radius: 6, x: 0, y: 2)
    }
}

可选调整

  • 如果需要强制至少选中一个项(不允许取消所有选中),将点击手势逻辑改为:
    selectedItemId = item.id
    
  • 可根据需求扩展样式,比如选中时的缩放动画、图标变化等。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:07:31