簡體   English   中英

SwiftUI 中月份的開始和結束日期

[英]Start and End date of month in SwiftUI

如何根據 SwiftUI 中的選定日期獲取 startDateOfMonth 和 endDateOfMonth?

我為 Swift (DateComponents) 找到了一些答案,但無法使其與 SwiftUI 一起使用。

為什么我需要這個:我將使用使用謂詞的動態過濾器來過濾當前選定月份中的所有數據(使用自定義控件切換月份)。 但首先我需要獲取每個選定月份的開始和結束日期。

示例代碼:

內容視圖.swift

import SwiftUI

struct ContentView: View {

    @State var currentDate = Date()

    // How to make startDateOfMonth and endDateOfMonth dependent on selected month?
    @State private var startDateOfMonth = "1st January"
    @State private var endDateOfMonth = "31st January"      

    var body: some View {

        VStack {
            DateView(date: $currentDate)

            Text("\(currentDate)")

            Text(startDateOfMonth)
            Text(endDateOfMonth)

        }

    }
}

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

日期視圖.swift

import SwiftUI

struct DateView: View {
    static let dateFormat: DateFormatter = {
        let formatter = DateFormatter()
        formatter.setLocalizedDateFormatFromTemplate("yyyy MMMM")
        return formatter
    }()

    @Binding var date : Date

    var body: some View {

        HStack {

            Image(systemName: "chevron.left")
                .padding()
                .onTapGesture {
                    print("Month -1")
                    self.changeDateBy(-1)
            }

            Spacer()

            Text("\(date, formatter: Self.dateFormat)")

            Spacer()

            Image(systemName: "chevron.right")
                .padding()
                .onTapGesture {
                    print("Month +1")
                    self.changeDateBy(1)
            }

        }
        .padding(EdgeInsets(top: 5, leading: 10, bottom: 5, trailing: 10))
        .background(Color.yellow)
    }

    func changeDateBy(_ months: Int) {
        if let date = Calendar.current.date(byAdding: .month, value: months, to: date) {
            self.date = date
        }
    }
}

struct DateView_Previews: PreviewProvider {

    struct BindingTestHolder: View {
        @State var testItem: Date = Date()
        var body: some View {
            DateView(date: $testItem)
        }
    }

    static var previews: some View {
        BindingTestHolder()
    }
}

我設法通過以下 ContentView 實現來解決它

@State var currentDate = Date()

private var startDateOfMonth: String {
    let components = Calendar.current.dateComponents([.year, .month], from: currentDate)
    let startOfMonth = Calendar.current.date(from: components)!
    return format(date: startOfMonth)
}

private var endDateOfMonth: String {
    var components = Calendar.current.dateComponents([.year, .month], from: currentDate)
    components.month = (components.month ?? 0) + 1
    components.hour = (components.hour ?? 0) - 1
    let endOfMonth = Calendar.current.date(from: components)!
    return format(date: endOfMonth)
}

var body: some View {
    VStack {
        DateView(date: $currentDate)
        Text("\(currentDate)")
        Text(startDateOfMonth)
        Text(endDateOfMonth)
    }
}

private func format(date: Date) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .medium
    return dateFormatter.string(from: date)
}

因為currentDate由 DateView 通過 Binding 更改,所以將調用主體計算屬性,因此startDateOfMonthendDateOfMonth計算屬性將返回更新后的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM