본문 바로가기

Project/30MinRead

❓ UICalendarSelectionMultiDate에서 특정 조건에서 선택을 막기! (UI 표시 X)

❓시작일, 종료일을 선택 한 후에, 다른 날짜 선택을 막을 수 있나? (UI 표시 안되게)

 

🚨 결론: UICalendarSelectionMultiDate에서는 선택을 즉시 해제할 방법이 없음.

즉, 세 번째 날짜를 선택했을 때, UI에서 즉시 해제(setSelected 등의 기능)를 제공하지 않음. 👉 사용자가 직접 선택을 취소해야 하는 방식으로 구현해야 함.

 

✅ 해결 방법

  1. 세 번째 날짜를 선택하면 경고창을 띄우고, "기존 선택을 해제하세요"라고 안내
  2. 사용자가 직접 기존 날짜를 해제한 후, 새로운 날짜를 선택하도록 유도
  3. 이미 선택된 날짜를 다시 누르면 자동으로 해제되도록 처리

=> 위의 방법은 오히려... 사용자 혼란이 옴.. 

 

 

 

✅ 최종수정 

  • 시작일과 종료일 사이의 일정도 표시되게 함 
  • 시작일, 종료일 선택 후 다른 날짜 선택시, 시작일과 종료일 중 가까운 날자와 변경 
extension DatePickerSheetViewController: UICalendarSelectionMultiDateDelegate {
    
    func multiDateSelection(_ selection: UICalendarSelectionMultiDate, didSelectDate dateComponents: DateComponents) {
        guard let newDate = dateComponents.date else { return }
        
       
        if selectedStartDate == nil {
            selectedStartDate = newDate
            selectedEndDate = newDate
        } else if selectedEndDate == nil {
            if newDate < selectedStartDate! {
                selectedEndDate = selectedStartDate
                selectedStartDate = newDate
            } else {
                selectedEndDate = newDate
            }
        } else {
            // ✅ 세 번째 날짜 선택 시, 기존 시작일/종료일 중 더 가까운 날짜를 변경
            let distanceToStart = abs(newDate.timeIntervalSince(selectedStartDate!))
            let distanceToEnd = abs(newDate.timeIntervalSince(selectedEndDate!))
            
            if distanceToStart < distanceToEnd {
                selectedStartDate = newDate
            } else {
                selectedEndDate = newDate
            }
        }
        
        selectDatesBetween(selection: selection, startDate: selectedStartDate!, endDate: selectedEndDate!)
    }
    
    
    func multiDateSelection(_ selection: UICalendarSelectionMultiDate, didDeselectDate dateComponents: DateComponents) {
        guard let date = dateComponents.date else { return }

        if date == selectedStartDate {
            selectedStartDate = nil
        } else if date == selectedEndDate {
            selectedEndDate = nil
        }
    }
    
    // ✅ 시작일과 종료일 사이의 모든 날짜를 자동으로 선택하는 함수
    private func selectDatesBetween(selection: UICalendarSelectionMultiDate, startDate: Date, endDate: Date) {
        
        let calendar = Calendar.current
        var currentDate = startDate
        
        while currentDate <= endDate {
            let dateComponents = calendar.dateComponents([.year, .month, .day], from: currentDate)
            selection.selectedDates.append(dateComponents) // ✅ 날짜 추가
            guard let nextDate = calendar.date(byAdding: .day, value: 1, to: currentDate) else { break }
            currentDate = nextDate
        }
    }
}