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

SwiftUI中如何修改LazyGrid内指定数量的元素样式?

解决方案

要实现选中指定数量网格元素并修改颜色的效果,核心是追踪每个元素在全局列表中的位置,判断是否属于目标范围。以下是修改后的完整代码:

import SwiftUI

struct ContentView: View {
    @State var showView = false
    @State private var birthDate = Date.now
    // 可调整的高亮元素数量
    private let highlightCount = 7
    
    struct Day: Identifiable {
        let id = UUID()
        let value: Int
    }
    
    struct Month {
        let name: String
        let numberOfDays: Int
        var days: [Day]

        init(name: String, numberOfDays: Int) {
            self.name = name
            self.numberOfDays = numberOfDays
            self.days = (1...numberOfDays).map { Day(value: $0) }
        }
    }
    
    let year = [
        Month(name: "Youth", numberOfDays: 12),
        Month(name: "Teenager", numberOfDays: 7),
        Month(name: "20s - 30s", numberOfDays: 20),
        Month(name: "Middle ages", numberOfDays: 26),
        Month(name: "Retirement", numberOfDays: 35),
    ]
    let layout = [
        GridItem(.flexible(minimum: 40)),
        GridItem(.flexible(minimum: 40)),
        GridItem(.flexible(minimum: 40)),
        GridItem(.flexible(minimum: 40)),
        GridItem(.flexible(minimum: 40)),
    ]
    
    var body: some View {
        VStack {
            DatePicker(selection: $birthDate, in: ...Date.now, displayedComponents: .date) {}
            Text("Your Birthdate is \(birthDate.formatted(date: .long, time: .omitted))")
            
            ScrollView {
                LazyVGrid(columns: layout, pinnedViews: [.sectionHeaders]) {
                    ForEach(year, id: \.name) { month in
                        // 计算当前月份之前的总天数
                        let cumulativeDaysBefore = year
                            .prefix(upTo: year.firstIndex(of: month)!)
                            .reduce(0) { $0 + $1.numberOfDays }
                        
                        Section(header: Text(verbatim: month.name).font(.headline)) {
                            ForEach(month.days) { day in
                                // 计算当前Day的全局索引(从0开始)
                                let globalIndex = cumulativeDaysBefore + day.value - 1
                                Capsule()
                                    .fill(globalIndex < highlightCount ? .black : .gray.opacity(0.3))
                                    .frame(height: 40)
                            }
                        }
                    }
                }.padding(5)
            }
        }
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

关键说明:

  • 高亮数量配置:直接修改highlightCount变量就能调整需要高亮的元素数量,比如改成20就会高亮前20个元素。
  • 全局位置计算:用cumulativeDaysBefore统计当前月份之前所有月份的总天数,结合当前Day的value(减1是因为value从1开始,索引从0计数),得到每个元素在全局列表中的位置。
  • 动态样式切换:根据globalIndex是否小于highlightCount,自动切换Capsule的填充颜色。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 12:01:07