EveryDiary - 캘린더 기능 개발

ulls12·2024년 2월 27일
0

Swift TIL

목록 보기
47/60
post-thumbnail

어떤 캘린더를 쓸까?

다이어리에서 캘린더 기능은 빠질 수 없다고 생각한다. 사용자가 쓴 일기를 캘린더를 통해서 한 눈에 바라볼 수 있어서 관리가 편하기 때문이다. 그럼, 어떤 종류의 캘린더를 써야할까? 처음에는 Apple에서 지원하는 캘린더기능이 빈약하고 외부 라이브러리로 쓰는 캘린더가 커스텀할 수 있는 방법과 적용이 매우 쉬워서 FSCalendar을 쓰려고 했다. 근데, Apple에서 2022년 중반기 즈음에 UICalendarView라는 프레임워크를 발표했고 실제로 적용해보니 외부 라이브러리와의 장단점이 명확했다.

  1. UICalendarView
  • 장점 : 개발자로서 접근성이 용이하고, 기본 세팅이 심플하고 세련되있다.
    Apple에서 개발한 프레임워크답게, 기본적인 기능들이 잘 구현되어있으며, 데이터 바인딩과 캘린더 데코레이션 등 기본 기능들이 강력하다.
  • 단점 : 캘린더에 추가적인 커스텀이 필요할 경우, 너무 복잡한 코드를 요구한다. 나온지 얼마 안된 프레임워크라 레퍼런스가 부족하다. 또한, 커스텀을 하기위한 속성들을 직접 찾아봐야한다.
    간단한 예를 들어, 토요일의 날짜 색을 파란색, 일요일의 날짜 색을 빨간색으로 바꾸려면 전체적인 코드를 뜯어고칠 수준의 코딩이 필요하다. 한마디로, 기본 기능은 강력하지만, 그 외의 커스텀을 하기 위한 시간 대비 아웃풋이 외부 라이브러리에 매우 떨어진다
  1. FSCalendar
  • 장점 : 커스텀이 매우 쉽고 다양하다. 오랫동안 서비스 해온 라이브러리인 만큼 레퍼런스가 정말 많고 속성값 설명도 잘 나와있다.
    확실히, Calendar을 구현하기 위해서는 FSCalendar를 그냥 써보라는 말을 들었는데, 직접 테스트 해보니 그 이유를 알 수 있었다. 우선, 캘린더 커스텀이 한줄 추가로 구현이 가능하도록 설정되어있었으며 심지어 기능이 많다..
  • 단점 : 외부 라이브러리이기 때문에 초기 세팅이 필요하다. 또한, 기본적인 디자인은 확실히 UICalendarView를 따라가지 못한다. 그만큼 디자인적으로 만족하려면, 커스텀에 더 투자해야된다.

우선, 나는 기존의 프레임워크를 하나라도 더 알아가는 게 좋다고 판단했고 무엇보다도 기본 디자인이 너무 간단명료하면서도 세련되었다고 생각해서 UICalendarView를 선택했다.

캘린더 기능 개발 일지

우선 다른 view component의 과정과 동일하게 진행된다.
1. calendarview 객체 생성

    private lazy var calendarView : UICalendarView = {
        var view = UICalendarView()
        view.wantsDateDecorations = true
        return view
    }()
  1. addSubview로 뷰 추가
  2. autolayout 잡기
    calendarView.snp.makeConstraints { make in
        make.centerX.equalTo(view)
        make.trailing.equalTo(view.safeAreaLayoutGuide.snp.trailing).offset(-10)
        make.top.equalTo(view.safeAreaLayoutGuide.snp.top).offset(10)
    }
  1. 다양한 메서드, 속성으로 캘린더 커스텀
//calendarVC
    private func customCalendar() {
        calendarView.tintColor = .mainTheme
        calendarView.backgroundColor = .mainCell
        calendarView.calendar = Calendar(identifier: .gregorian)
        calendarView.locale = Locale(identifier: "ko-KR")
        calendarView.fontDesign = .rounded
        calendarView.layer.cornerRadius = 10
        calendarView.delegate = self
    }
    // 날짜를 탭했을 때, delegete 설정
    private func dateSelectCalendar() {
        let dataSelection = UICalendarSelectionSingleDate(delegate: self)
        calendarView.selectionBehavior = dataSelection
    }
    // 날짜 구간 설정, 2024년 이전으로는 설정 불가
    private func setDateComponents() {
        let fromDateComponents = DateComponents(
            calendar: calendarView.calendar,
            year: 2024,
            month: 1,
            day: 1
        )
        guard let fromDate = fromDateComponents.date else {
            fatalError("Invalid date components: \(fromDateComponents)")
        }
        let calendarViewDateRange = DateInterval(start: fromDate, end: .distantFuture)
        calendarView.availableDateRange = calendarViewDateRange
    }
}
  1. 캘린더 데이터 흐름 구성
extension CalendarVC: UICalendarViewDelegate, UICalendarSelectionSingleDateDelegate {
	//날짜 선택했을 시, 메서드 구성
    func dateSelection(_ selection: UICalendarSelectionSingleDate, didSelectDate dateComponents: DateComponents?) {
        let vc = DiaryListVC()
        vc.hidesBottomBarWhenPushed = true
        navigationController?.pushViewController(vc, animated: true)
    }
    //날짜에 데이터를 추가하여 표현하는 방법 구성
    func calendarView(_ calendarView: UICalendarView, decorationFor dateComponents: DateComponents) -> UICalendarView.Decoration? {
        guard let day = dateComponents.day else {
            return nil
        }
        //짝수날은 불 꺼진 상태, 홀수날은 불 켜진 상태 구성
        if day.isMultiple(of: 2) {
            return .default(color: .subBackground, size: .medium)
        } else {
            return .default(color: .mainTheme, size: .medium)
        }
        
    }
    //날짜를 선택할 수 있는 조건 구성
    func dateSelection(_ selection: UICalendarSelectionSingleDate, canSelectDate dateComponents: DateComponents?) -> Bool {
        guard let day = dateComponents?.day else { return false }
        // 짝수날은 비활성, 홀수날은 활성 상태 구성
        if day % 2 == 0 {
            return false
        } else {
            return true
        }
    }
}

사실 우리의 집중 전략은 캘린더에 있지 않기 때문에, 기본적인 기능에 충실한 UICalendarView 만으로도 충분하다고 판단했다. 캘린더는 데이터 바인딩을 통해 일기를 쓴 날에만 날짜를 선택할 수 있게 하며, 선택된 날짜의 일기를 새로운 뷰를 통해 보여줄 수 있도록 로직을 짜야한다. 우선 기초 틀은 완성이 되었다

결과물

profile
I am 개발해요

0개의 댓글