在 SwiftUI 中将 ObservableObject 链接到 DatePicker

Posted

技术标签:

【中文标题】在 SwiftUI 中将 ObservableObject 链接到 DatePicker【英文标题】:Linking ObservableObject to DatePicker in SwiftUI 【发布时间】:2021-07-06 22:13:21 【问题描述】:

我是 Swift 及其所有框架的新手。我有一个 JSON 文件,其中包含一年中每一天的读数。我为读数创建了一个Decodable 结构和一个将读数存储在数组中的ObservableObject 类。我已将ObservableObject 设为@EnvironmentObject,因此可以在所有视图中访问它。我可以将读数链接到日期选择器,以便选择日期将带我进入详细视图吗?

import SwiftUI

struct CalendarView: View 
    // this is where ObserveableObject is required
    @EnvironmentObject var days: Days
    
    @State private var date = Date()
    
    let dateFormatter: DateFormatter = 
       let formatter = DateFormatter()
        // formatter.dateStyle = .long
        formatter.dateFormat = "LLLL d"
        return formatter
    ()
    
    var body: some View 
        VStack 
            Text("Select a date to read")
                .font(.largeTitle)
            
            DatePicker("Select a date", selection: $date, displayedComponents: .date)
                .datePickerStyle(GraphicalDatePickerStyle())
                .labelsHidden()
                .frame(maxHeight: 400)
            
            Text("\(date, formatter: dateFormatter)")
        
        .navigationTitle("Datepicker")
    


struct CalendarView_Previews: PreviewProvider 
    static var previews: some View 
        CalendarView()
    

【问题讨论】:

【参考方案1】:
//Replace this with your Decodable object
class Day : ObservableObject
    let id: UUID = UUID()
    var date: Date
    init( date: Date) 
        self.date = date
    

class CalendarViewModel: ObservableObject, Identifiable 
    
    @Published var days: [Day] = []
    @Published var selectedDate: Date = Date()
    
    var filteredDay: Day?
        days.filter(
            Calendar.current.isDate($0.date, equalTo: selectedDate, toGranularity: .day)
        ).first
    
    
    init() 
        //Create sample Days you can remove this and populate your array with acual data
        for n in 1...30
            days.append(Day(date: Date().addingTimeInterval(TimeInterval(60*60*24*n))))
            days.append(Day(date: Date().addingTimeInterval(TimeInterval(-60*60*24*n))))
        
    

struct CalendarView: View 
    @StateObject var vm: CalendarViewModel = CalendarViewModel()
    
    @State var isVisible: Bool = false
    let dateFormatter: DateFormatter = 
        let formatter = DateFormatter()
        // formatter.dateStyle = .long
        formatter.dateFormat = "LLLL d"
        return formatter
    ()
    
    var body: some View 
        NavigationView
            ScrollView 
                Text("Select a date to read")
                    .font(.largeTitle)
                
                DatePicker("Select a date", selection: $vm.selectedDate, displayedComponents: .date)
                    .datePickerStyle(GraphicalDatePickerStyle())
                    .labelsHidden()
                    .frame(maxHeight: 400)
                
                Text("\(vm.selectedDate, formatter: dateFormatter)")
                
                if vm.filteredDay != nil
                    NavigationLink(
                        destination: DayView(day: vm.filteredDay!),
                        isActive: $isVisible,
                        label: 
                            Text("View Day")
                        )
                else
                    Text("No results for selected day")
                
                
            
            .navigationTitle("Datepicker")
        
    
    

struct DayView:View 
    //Observe the actual Day here for changes
    @ObservedObject var day: Day
    let dateFormatter: DateFormatter = 
        let formatter = DateFormatter()
        // formatter.dateStyle = .long
        formatter.dateFormat = "LLLL d"
        return formatter
    ()
    var body: some View 
        VStack
            Text(dateFormatter.string(from: day.date))
        
    

【讨论】:

以上是关于在 SwiftUI 中将 ObservableObject 链接到 DatePicker的主要内容,如果未能解决你的问题,请参考以下文章

如何在swiftui中将vstack移动到屏幕顶部?

在 SwiftUI 中将部分文本加粗

如何在swiftUI中将背景颜色添加到列表中

如何在 SwiftUI 中将 TabView 与 NavigationView 一起使用?

如何在 SwiftUI 中将 LocalizedStringKey 更改为 String

在 ScrollView 中将文本对齐为前导 - SWIFTUI