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

SwiftUI 如何获取月份每一天对应的星期名称并完成展示?

实现方案

修改步骤

1. 扩展DateProvider功能

新增两个工具方法:一个用于获取指定日期对应的星期名称,另一个用于获取指定月份第一天的偏移量,保证日历排版对齐。
修改后的完整DateProvider代码如下:

class DateProvider: ObservableObject {
    
    @Published var months: [String] = []
    @Published var dateData: DateType = DateType(day: "", date: "", year: "", month: "")
    
    private let trLocale = NSLocale(localeIdentifier: "tr_TR") as Locale
    
    init() {
        months = getMonths()
        dateData = getCurrentDate()
    }
    
    func getCurrentDate() -> DateType {
        let date = Date()
        var currentDate = Calendar.current
        currentDate.locale = trLocale
        let dateString = currentDate.component(.day, from: date)
        let monthNo = currentDate.component(.month, from: date)
        let month = currentDate.monthSymbols[monthNo - 1]
        let year = currentDate.component(.year, from: date)
        let weekNo = currentDate.component(.weekday, from: date)
        let day = currentDate.weekdaySymbols[weekNo - 1]
        return DateType(day: "\(day)", date: "\(dateString)", year: "\(year)", month: "\(month)")
    }
    
    func getMonths() -> [String] {
        let formatter = DateFormatter()
        formatter.locale = trLocale
        let monthComponents = formatter.shortMonthSymbols ?? []
        return monthComponents
    }
    
    func getNumbersOfMonths(month: Int, year: Int) -> Int {
        let dateComponents = DateComponents(year: year, month: month)
        let calendar = Calendar.current
        let date = calendar.date(from: dateComponents)!
        let range = calendar.range(of: .day, in: .month, for: date)!
        let numDays = range.count
        return numDays + 1
    }
    
    // 新增:获取指定日期的星期名称
    func getWeekday(day: Int, month: Int, year: Int) -> String {
        var calendar = Calendar.current
        calendar.locale = trLocale
        let components = DateComponents(year: year, month: month, day: day)
        guard let date = calendar.date(from: components) else { return "" }
        let weekdayIndex = calendar.component(.weekday, from: date)
        // 如需完整星期名可替换为weekdaySymbols
        return calendar.shortWeekdaySymbols[weekdayIndex - 1]
    }
    
    // 新增:获取月份第一天的偏移量,用于填充前置空位
    func getFirstDayOffset(month: Int, year: Int) -> Int {
        var calendar = Calendar.current
        calendar.locale = trLocale
        let components = DateComponents(year: year, month: month, day: 1)
        guard let date = calendar.date(from: components) else { return 0 }
        return calendar.component(.weekday, from: date) - 1
    }
}

2. 修改ContentView布局

调整LazyVGrid内的布局,先填充前置空位,再在每个日期下方新增星期名展示。修改后的完整ContentView代码如下:

struct ContentView: View {
    @State var data: DateType = DateType(day: "", date: "", year: "", month: "")
    @ObservedObject var dateProvider: DateProvider = DateProvider()
    // 固定展示2021年,可根据需求修改为动态变量
    private let displayYear = 2021
    
    var body: some View {
        ScrollView {
            VStack(spacing: 20) {
                VStack(spacing: 8) {
                    Text(self.dateProvider.dateData.day)
                    Text(self.dateProvider.dateData.date)
                    Text(self.dateProvider.dateData.month)
                    Text(self.dateProvider.dateData.year)
                }
                
                VStack(spacing: 30) {
                    ForEach(dateProvider.months.indices, id: \.self) { index in
                        let currentMonth = index + 1
                        Text("\(dateProvider.months[index])")
                            .font(.title2)
                            .fontWeight(.medium)
                        
                        LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 7), spacing: 10) {
                            // 填充月份第一天前的空位
                            ForEach(0 ..< dateProvider.getFirstDayOffset(month: currentMonth, year: displayYear), id: \.self) { _ in
                                EmptyView()
                            }
                            // 日期+星期展示
                            ForEach(1 ..< dateProvider.getNumbersOfMonths(month: currentMonth, year: displayYear)) { item in
                                VStack(spacing: 4) {
                                    Text("\(item)")
                                        .font(.headline)
                                    Text(dateProvider.getWeekday(day: item, month: currentMonth, year: displayYear))
                                        .font(.caption)
                                        .foregroundColor(.secondary)
                                }
                            }
                        }
                        .padding(.horizontal)
                    }
                }
            }
            .padding(.vertical)
        }
    }
}

3. 原有Model无需修改

DateType结构体保持原有定义即可。

内容的提问来源于stack exchange,提问作者Ufuk Köşker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 01:45:02