[英]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:你有两个选择:
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)
@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.