import SwiftUI
struct CustomDatePicker: View {
@Binding var currentDate : Date
let column = Array(repeating: GridItem(.flexible()), count: 7)
let dates : [String] = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
@State var currentMonth = 0
var body: some View {
VStack {
HStack {
VStack {
Text(extraDate()[0])
Text(extraDate()[1])
}
.padding()
Spacer()
Button(action: {
currentMonth -= 1
}, label: {
Image(systemName: "chevron.left")
.frame(width : 30, height : 30)
.background(.blue)
.foregroundColor(.white)
.mask(Rectangle())
.cornerRadius(10)
})
Button(action: {
currentMonth += 1
}, label: {
Image(systemName: "chevron.right")
.frame(width : 30, height : 30)
.background(.blue)
.foregroundColor(.white)
.mask(Rectangle())
.cornerRadius(10)
})
.padding()
}
HStack(spacing: 25) {
ForEach(dates, id: \.self) { item in
Text(item)
}
}
LazyVGrid(columns: column) {
ForEach(extractDate()) { item in
cardView(value: item)
.background(
Capsule()
.fill(.pink)
.padding(.horizontal, 8)
.opacity(isSameDay(date1: item.date, date2: currentDate) ? 1 : 0)
)
.onTapGesture {
withAnimation(.default) {
currentDate = item.date
}
}
}
}
.onChange(of: currentMonth) { newValue in
currentDate = getCurrentMonth()
}
}
.padding()
VStack {
Text("Tasks")
if let task = tasks.first(where: { task in
return isSameDay(date1: task.taskDate, date2: currentDate)
}) {
ForEach(task.task) { task in
HStack {
Text(task.time.addingTimeInterval(300), style : .time)
Text(task.title) // 타임 어라이벌에 들어가는 숫자는 초단위이다. 지금은 5분 뒤로 타임이 책정된 상태이다. 300넣어두면 5분 뒤로 책ㄷ정된다.
}
}
}
}
}
}
extension CustomDatePicker {
@ViewBuilder
func cardView(value : DateValue) -> some View {
VStack {
if value.day != -1 {
if let task = tasks.first(where: { task in
return isSameDay(date1: task.taskDate, date2: value.date)
}) {
Text("\(value.day)")
.font(.title3.bold())
.foregroundColor(isSameDay(date1: task.taskDate, date2: currentDate) ? .white : .primary)
.frame(maxWidth : .infinity)
Spacer()
Circle()
.fill(isSameDay(date1: task.taskDate, date2: currentDate) ? .white : .pink)
.frame(width : 8, height : 8)
} else {
Text("\(value.day)")
.font(.title3.bold())
.foregroundColor(isSameDay(date1: value.date, date2: currentDate) ? .white : .primary)
.frame(maxWidth : .infinity)
Spacer()
}
}
}
.padding(.vertical, 5)
.frame(height : 60)
}
func isSameDay(date1 : Date, date2 : Date) -> Bool {
let calendar = Calendar.current
return calendar.isDate(date1, inSameDayAs: date2)
}
func getCurrentMonth() -> Date {
let calendar = Calendar.current
guard let currentMonth = calendar.date(byAdding: .month, value: self.currentMonth, to: Date())
else { return Date() }
return currentMonth // 다음은 현재 무슨 달인지를 알아낸다.
}
func extractDate() -> [DateValue] {
let calendar = Calendar.current
let currentMonth = getCurrentMonth()
var days = currentMonth.getAllDate().compactMap { date -> DateValue in
let day = calendar.component(.day, from: date)
return DateValue(day: day, date: date)
}
let firstWeekday = calendar.component(.weekday, from: days.first?.date ?? Date())
for _ in 0..<firstWeekday - 1 {
days.insert(DateValue(day: -1, date: Date()), at: 0)
}
return days
} // 해당 달이 가지고 있는 날짜를 모두 뽑아낸다.
func extraDate() -> [String] {
let formatter = DateFormatter()
formatter.dateFormat = "YYYY MMMM"
let date = formatter.string(from: currentDate)
return date.components(separatedBy: " ")
} // 얘는 단순하게 데이트의 포매팅 상태를 지정해주는 것이다. 스페이스를 통해서 분할된 날짜를 배열로 뽑아내준다.
}
extension Date {
func getAllDate() -> [Date] { // 1. 캘린더에서 모든 데이트를 뽑아낸다. 데이트의 배열로 가져올 것이다.
let calendar = Calendar.current
let startDate = calendar.date(from: Calendar.current.dateComponents([.year, .month], from: self))!
let range = calendar.range(of: .day, in: .month, for: startDate)!
return range.compactMap { day -> Date in
return calendar.date(byAdding: .day, value: day-1, to: startDate)!
}
}
}
This is the code for monthly calendar. However I want to make weekly calendar, by handling some code in this.
for example if I click the, right or left button, I want to see 7 numbers for week
mon tue wed thu fri sat sun 31. 1. 2. 3. 4. 5. 6.
like this.
Can you help me? I think I have to change the range for date and date but I can't know.