问题描述
我正在尝试将我的 JSON 数据加载到 FSCalendar。
我从文档中了解到,当您使用可以在日历中用点显示的数组时。我想做同样的事情,而是让点从我的 JSON 文件中列出的日期中出现。我已将 JSON 文件加载到我的包中,并创建了一个加载 JSON 数据的函数,并创建了一个结构。
当我尝试使用结构中的数组然后将该数组加载到“func calendar(_ calendar: FSCalendar,numberOfEventsFor date: Date) -> Int {”函数时,我的问题就出现了。我已经在这方面工作了一段时间,可以使用一些帮助。谢谢
JSON 数据: - 我将 JSON 文件命名为 data.json
[
{
"event": "Christmas","date": [
"2021-01-02","2021-01-03","2021-01-04"
]
}
]
视图控制器:
import UIKit
import FSCalendar
class ViewController: UIViewController,FSCalendarDelegate,FSCalendarDataSource,FSCalendarDelegateAppearance {
//MARK: - calendar variables
@IBOutlet var calendar: FSCalendar!
@IBOutlet weak var dateLabel: UILabel!
fileprivate let gregorian: Calendar = Calendar(identifier: .gregorian)
fileprivate lazy var dateFormatter1: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd"
return formatter
}()
fileprivate lazy var dateFormatter2: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
// These are just test data to see the dots on the calendar
var datesWithEvents = ["2021-01-15","2021-01-16","2021-01-17","2021-01-18"]
var datesWithMultipleEvents = ["2021-01-20","2021-01-21","2021-01-22","2021-01-23"]
//MARK: - JSON variable
// var result: Results?
let data = DataLoader().eventData
//MARK: - viewdidload
override func viewDidLoad() {
super.viewDidLoad()
// parseJSON()
let data = DataLoader().eventData
print(data)
calendar.delegate = self
calendar.dataSource = self
}
deinit {
print("\(#function)")
}
//MARK: - calendar functions
func calendar(_ calendar: FSCalendar,didSelect date: Date,at monthPosition: FSCalendarMonthPosition) {
let formatter = DateFormatter()
formatter.dateFormat = "EEEE MM-dd-YYYY"
let string = formatter.string(from: date)
print("\(string)")
}
func calendar(_ calendar: FSCalendar,appearance: FSCalendarappearance,eventDefaultColorsFor date: Date) -> [UIColor]? {
let key = self.dateFormatter2.string(from: date)
// this is the test with the hard coded arrays,I think i need to
implement the JSON here but am not sure how
if self.datesWithMultipleEvents.contains(key) {
return [UIColor.magenta,appearance.eventDefaultColor,UIColor.red]
}
return nil
}
func calendar(_ calendar: FSCalendar,numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter2.string(from: date)
if self.datesWithEvents.contains(dateString) {
return 1
}
if self.datesWithMultipleEvents.contains(dateString) {
return 3
}
return 0
}
数据模型:
struct EventsData: Codable {
var event: String
var date: [String]
}
JSON 加载器:
import Foundation
public class DataLoader {
@Published var eventData = [EventsData]()
init() {
load()
}
func load() {
if let fileLocation = Bundle.main.url(forResource: "data",withExtension: "json") {
//do catch incase of error
do {
let data = try Data(contentsOf: fileLocation)
let jsonDecoder = JSONDecoder()
let dataFromJson = try jsonDecoder.decode([EventsData].self,from: data)
self.eventData = dataFromJson
} catch {
print(error)
}
}
}
}
编辑:
func calendar(_ calendar: FSCalendar,numberOfEventsFor date: Date) -> Int {
let dateString = self.dateFormatter2.string(from: date)
if self.eventData.contains(where: //<#T##(EventsData) throws -> Bool#>) //How to get this to do the contains like in the next if statement
if self.datesWithEvents.contains(dateString) {
return 1
}
if self.datesWithMultipleEvents.contains(dateString) {
return 3
}
return 0
}
解决方法
检查你的代码中是否有这个:
// FSCalendarDataSource
func calendar(calendar: FSCalendar!,hasEventForDate date: NSDate!) -> Bool {
return shouldShowEventDot
}
,
只需使用 DateFormatter 将您的字符串日期转换为 Date,然后只需遍历您的数组并检查日期(来自日历函数)是否与您在事件中的任何日期匹配。
,你有很多问题。
首先,您尝试在 Swift 应用中使用 SwiftUI 构造 (@Published
)。那行不通。
其次,您将日期作为字符串数组输入。我建议使用自定义 Date
解码策略来设置您的 Codable 协议一致性。
This link 展示了如何设置 JSONDecoder 以使用采用自定义 DateFormatter 的自定义日期解码策略。
接下来,当从您的 JSON 输入读取新数据时,您需要某种方式来更新您的 UI。 SwiftUI 具有自动响应状态更改的内置机制,但您没有使用 SwiftUI,因此这些不适用。
您有一个加载 JSON 数据的 DataLoader
类。它目前从文件中同步读取硬编码的 JSON。我假设您想从互联网加载数据,这将是异步的。因此,您的方法将不起作用。
我建议您将 DataLoader
类设置为具有一个在完成加载新数据时通知的委托,或者将其设置为使用完成处理程序接收请求。
如果您不知道如何做其中任何一件事情,那么您需要停下来学习一些基础知识。在继续之前阅读 Swift 异步网络、完成处理程序和委托设计模式。