Дата начала и окончания месяца в SwiftUI - PullRequest
0 голосов
/ 07 января 2020

Как получить startDateOfMonth и endDateOfMonth на основе выбранной даты в SwiftUI?

Я нашел несколько ответов для Swift (DateComponents), но не смог заставить его работать с SwiftUI.

Зачем мне это нужно: я собираюсь использовать динамические фильтры c, используя предикат для фильтрации всех данных в текущем выбранном месяце (используя пользовательский элемент управления для переключения месяцев). Но сначала мне нужно получить даты начала и окончания для выбранного месяца.

ПРИМЕР кода:

ContentView.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()
    }
}

DateView.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()
    }
}

1 Ответ

1 голос
/ 07 января 2020

Мне удалось решить эту проблему с помощью следующей реализации 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)
}

Поскольку DateView изменяет currentDate через связывание, вычисляется свойство body, таким образом, вычисляются свойства startDateOfMonth и endDateOfMonth вернет обновленные значения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...