I am a designer and try to develop a to-do list app. In the app, user select one day in calendar, it will to shows to-do list of selected day. But how can i pass selected date from FSCalendar(UIKIT) to to-do list(SwiftUI)?
Thanks so much!
My app demo in github: https://github.com/ElvishR/FSCalendar-To-Do-List-Test.git
Content View:
import SwiftUI
import Foundation
class UserData: ObservableObject{
@Published var name = "Helsdfsflo"
}
struct ContentView: View {
@ObservedObject var userData = UserData()
var body: some View {
Text(userData.name)
Button(action:{
print(self.userData.name)
}){
Text(" click to show the selected date")
}
CalendarModuleView()
.frame(width: .infinity, height: 300.0, alignment: .center)
}
}
Calendar View
import SwiftUI
import FSCalendar
class CalendarModule: UIViewController, FSCalendarDelegate {
var calendar = FSCalendar()
var formatter = DateFormatter()
var SelectedDate = ""
let integration = UserData()
fileprivate lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd"
return formatter
}()
override func viewDidLoad() {
super.viewDidLoad()
calendar.delegate = self
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
initCalendar()
view.addSubview(calendar)
}
private func initCalendar() {
calendar.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 300.0)
calendar.appearance.todayColor = UIColor.systemGreen
calendar.appearance.selectionColor = UIColor.systemBlue
}
//selected day
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition){
// Do the same inside this function and you should be fine
formatter.dateFormat = "yyyy-MM-dd"
SelectedDate = formatter.string(from: date)
ContentView().userData.name = formatter.string(from: date)
print(ContentView().userData.name)
print("calendar did select date \(self.formatter.string(from: date))")
}
func calendar(calendar: FSCalendar!, didSelectDate date: NSDate!) {
formatter.dateFormat = "yyyy-MM-dd"
SelectedDate = formatter.string(from: date as Date)
print("(self.formatter.string(from: date))")
}
}
APP Screenshot enter image description here
Use the UIViewRepresentable
protocol for bind UIView class with SwiftUI.
Here is a demo:
struct CalendarModuleView: UIViewRepresentable {
@Binding var selectedDate: Date?
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> FSCalendar {
let calendar = FSCalendar()
calendar.delegate = context.coordinator
calendar.appearance.todayColor = UIColor.systemGreen
calendar.appearance.selectionColor = UIColor.systemBlue
return calendar
}
func updateUIView(_ uiView: FSCalendar, context: Context) {
}
class Coordinator: NSObject, FSCalendarDelegate {
var parent: CalendarModuleView
init(_ calender: CalendarModuleView) {
self.parent = calender
}
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
self.parent.selectedDate = date
}
}
}
Your ContentView
class UserData: ObservableObject{
@Published var name = "Helsdfsflo"
@Published var date: Date?
}
struct ContentView: View {
@ObservedObject private var userData = UserData()
static let taskDateFormat: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
var body: some View {
Text(userData.name)
if userData.date != nil {
Text("Task due date: \(userData.date!, formatter: Self.taskDateFormat)")
}
Button(action:{
print(self.userData.name)
}){
Text(" click to show the selected date")
}
CalendarModuleView(selectedDate: $userData.date)
.frame(height: 300.0, alignment: .center)
}
}