SwiftUI : How I can handle this Monthly calendar to weekly Calendar

Viewed 291
    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.

0 Answers
Related