简体   繁体   English

如何在所有视图中同时更改日期?

[英]How to make the date change simultaneously in all views?

Date not change simultaneously in all views.日期不会在所有视图中同时更改。 I want to link two calendars.我想链接两个日历。 Standard and custom.标准和定制。 But they don't connect.但他们没有联系。 When I change the date in one, it doesn't change in the other.当我更改一个中的日期时,另一个中的日期不会改变。 I made Published:我发表了:

import Combine
import Foundation

class CustomCalendar: ObservableObject {
    @Published var currentDate = Date()
    var currentThreeWeek: [Date] = []

    init() {
        fetchCurrentThreeWeek()
    }

    func fetchCurrentThreeWeek() {

        let calendar = Calendar.current

        var todayDay = DateInterval(start: Date(), duration: 1814400).start
        let lastDay = DateInterval(start: Date(), duration: 1814400).end

        currentThreeWeek.append(todayDay)

        while todayDay < lastDay {
            todayDay = calendar.date(byAdding: .day, value: 1, to: todayDay)!
            currentThreeWeek.append(todayDay)
        }
    }

    func extractDate(date: Date, format: String) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        dateFormatter.locale = Locale(identifier: "rus")
        return dateFormatter.string(from: date)
    }

    func isToday(date: Date) -> Bool {
        let calendar = Calendar.current
        return calendar.isDate(currentDate, inSameDayAs: date)
    }
}

When I select a date it doesn't change in other views.当我 select 一个日期时,它在其他视图中没有改变。

import SwiftUI

struct FilterView: View {

    @StateObject private var calendar = CustomCalendar()
    @Binding var filterViewIsPresented: Bool
    
    let todayDay = DateInterval(start: Date(), duration: 1814400).start
    let lastDay = DateInterval(start: Date(), duration: 1814400).end

    var body: some View {
        VStack {
            DatePicker("", selection: $calendar.currentDate, in: todayDay...lastDay, displayedComponents: .date)
                .labelsHidden()
                .environment(\.locale, Locale.init(identifier: "ru"))
            HorizontalCalendarView()
            HorizontalCalendarView()
        }
    }
}

struct FilterView_Previews: PreviewProvider {
    static var previews: some View {
        FilterView(filterViewIsPresented: .constant(false))
    }
}

Custom calendar.自定义日历。 On tap Gesture I change currentDate点击手势我改变 currentDate


import SwiftUI

struct HorizontalCalendarView: View {

    @StateObject private var calendar = CustomCalendar()

    var body: some View {
        ScrollViewReader { value in
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 0) {
                    ForEach(calendar.currentThreeWeek, id: \.self) { day in
                        VStack(spacing: 0) {

                            Text(calendar.extractDate(date: day, format: "dd"))
                                .font(.title3)
                                .fontWeight(.bold)

                            Text(calendar.extractDate(date: day, format: "EEE"))

                            RoundedRectangle(cornerRadius: 10, style: .continuous)
                                .frame(width: calendar.isToday(date: day) ? 40 : 0, height: 5)
                                .opacity(calendar.isToday(date: day) ? 1 : 0)
                                .padding(4)
                        }
                        .frame(width: 45, height: 45)
                        .foregroundStyle(calendar.isToday(date: day) ? .primary : .secondary )
                        .foregroundColor(calendar.isToday(date: day) ? .white : .black)
                        .padding(8)
                        .background(
                            ZStack {
                                if calendar.isToday(date: day) {
                                    RoundedRectangle(cornerRadius: 10, style: .continuous)
                                }
                            }
                        )
                        .onTapGesture {
                            withAnimation(.easeIn(duration: 0.2)) {
                                calendar.currentDate = day
                                value.scrollTo(calendar.currentDate, anchor: .leading)
                            }
                        }
                    }
                    .padding(9)
                }
            }
            Text(calendar.currentDate.formatted())
        }
    }
}

struct HorizontalCalendarView_Previews: PreviewProvider {
    static var previews: some View {
        HorizontalCalendarView()
    }
}


How can I do this?我怎样才能做到这一点?

You have two options:你有两个选择:

  1. Pass calendar in HorizontalCalendarView constructor and use @ObservedObject property wrapper instead of @StateObject :在 Horizo HorizontalCalendarView构造函数中传递日历并使用@ObservedObject属性包装器而不是@StateObject

struct HorizontalCalendarView: View {

    @ObservedObject private var calendar: CustomCalendar

    init(_ calendar: CustomCalendar) {
        self.calendar = calendar
    }

...

and just pass it in FilterView然后将它传递给FilterView

HorizontalCalendarView(calendar)
  1. Another option is to use @EnvironmentObject (it's preferred method for deeply nested views in your example option 1 is better):另一种选择是使用@EnvironmentObject (在您的示例选项 1 中,深度嵌套视图的首选方法更好):
struct HorizontalCalendarView: View {

    @EnvironmentObject private var calendar: CustomCalendar = CustomCalendar()

...

then you have to pass calendar with environmentObject modifier:那么你必须通过environmentObject修饰符传递日历:

HorizontalCalendarView().environmentObject(calendar)

Note: in order to @EnvironmentObject works as expected it is not necessary to use environmentObject modifier on actual view, you can use this modifier in any of parent views.注意:为了@EnvironmentObject按预期工作,没有必要在实际视图上使用environmentObject修饰符,您可以在任何父视图中使用此修饰符。 That makes it perfect for deep nested views这使得它非常适合深层嵌套视图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM