[iOS] FSCalendar - 주간 캘린더 & 커스텀

David·2023년 6월 11일
1

라이브러리

목록 보기
1/1
post-thumbnail

FSCalendar는 iOS에서 캘린더를 직접 구현하지 않고, 가져다 쓸 수 있는 캘린더 라이브러리입니다.

이번에 해커톤을 진행하면서, 직접 구현하기에는 시간적 제약이 있어 관련 라이브러리를 찾다가 발견해서 사용해봤습니다. 사용하면서 설정했던 부분들을 공유하겠습니다.

하단 링크를 통해 예시나 설치하는 방법을 알 수 있어요.
https://github.com/WenchaoD/FSCalendar

주간 달력 설정

FSCalendar에서는 달력 모드를 주간 혹은 월간으로 설정할 수 있습니다.

private let calendar : FSCalendar = {
        let calendar = FSCalendar(frame: .zero)
        calendar.scope = .week // 주간 달력 설정
        calendar.scope = .month // 월간 달력 설정
        return calendar
    }()

Delegate 설정

calendar.delegate = self
calendar.dataSource = self

요일 관련 설정

FSCalendar에서는 요일(월~일)부분을 설정하실 때는 weekday 관련 키워드로 보시면 됩니다.

private let calendar : FSCalendar = {
        let calendar = FSCalendar(frame: .zero)
        calendar.weekdayHeight // 높이 설정
		calendar.appearance.weekdayFont // 폰트 설정
        calendar.appearance.weekdayTextColor // 텍스트 컬러 설정
        calendar.locale = Locale(identifier: "us_US") // 요일 설정 us면 Mon, ko_KR 이면 월,화...
        calendar.firstWeekday = 2 // 기본 설정은 일요일(일~토)이 시작이나, 2로 설정하면 월요일부터 시작합니다(월~일)
        return calendar
    }()

일수 관련 설정

private let calendar : FSCalendar = {
        let calendar = FSCalendar(frame: .zero)
        calendar.appearance.titleFont // 일(1,2,3...) 폰트 설정
        calendar.appearance.titleDefaultColor // 선택되지 않은 날의 기본 컬러 설정
        calendar.appearance.titleSelectionColor // 선택된 날의 컬러 설정
        calendar.appearance.titlTodayColor // 금일 컬러 설정
        return calendar
    }()

select 설정

FSCalendar에서 날짜를 선택했을 때, default 값으로 일수를 둘러싼 동그라미가 나옵니다.

전 이 동그라미가 싫어서, 하단과 같이 설정해주었습니다.

private let calendar : FSCalendar = {
        let calendar = FSCalendar(frame: .zero)
        calendar.appearance.selectionColor = .clear
        return calendar
    }()


오늘 날짜도 동그라미가 보기 싫어서 클리어 처리하겠습니다.

private let calendar : FSCalendar = {
        let calendar = FSCalendar(frame: .zero)
        calendar.appearance.todayColor = .clear
        return calendar
    }()

주간 달력 커스텀

FSCalendar는 밑에서 보는 것처럼 기존 설정이 스와이프를 통한 넘김입니다. 전 버튼을 통해 달력 이동을 하고 싶었고, yyyy년 mm월을 원하는 곳에 두고 싶었습니다.

// yyyy년 mm월 
private let titleLabel : UILabel = {
        let label = UILabel()
        label.text = ""
        return label
    }()
    
    // 이전 주 이동 버튼
    private lazy var previousButton : UIButton = {
        let button = UIButton()
        button.setImage(UIImage(systemName: "chevron.left"), for: .normal)
        button.addTarget(self, action: #selector(prevCurrentPage), for: .touchUpInside)
        return button
    }()
    // 다음 주 이동 버튼
    private lazy var nextButton : UIButton = {
        let button = UIButton()
        button.setImage(UIImage(systemName: "chevron.right"), for: .normal)
        button.addTarget(self, action: #selector(nextCurrentPage), for: .touchUpInside)
        return button
    }()
    
    private var currentPage: Date?
    
    private let today: Date = {
        return Date()
    }()
    // 다음 주로 이동 함수
    @objc private func nextCurrentPage(isPrev: Bool) {
        let cal = Calendar.current
        var dateComponents = DateComponents()
        dateComponents.weekOfMonth = 1
        
        self.currentPage = cal.date(byAdding: dateComponents, to: self.currentPage ?? self.today)
        self.calendar.setCurrentPage(self.currentPage!, animated: true)
    }
    // 이전 주로 이동 함수
    @objc private func prevCurrentPage(isPrev: Bool) {
        let cal = Calendar.current
        var dateComponents = DateComponents()
        dateComponents.weekOfMonth = -1
        
        self.currentPage = cal.date(byAdding: dateComponents, to: self.currentPage ?? self.today)
        self.calendar.setCurrentPage(self.currentPage!, animated: true)
    }
    // mm월이 바뀌면 자동으로 변경
    extension ViewController: FSCalendarDelegate, FSCalendarDataSource, FSCalendarDelegateAppearance {
    func calendarCurrentPageDidChange(_ calendar: FSCalendar) {
        self.titleLabel.text = self.dateFormatter.string(from: calendar.currentPage)
    }
}

위와 같이 만들고, 기존 캘린더의 헤더를 아래의 코드를 통해 없애주면 됩니다.

private let calendar : FSCalendar = {
        let calendar = FSCalendar(frame: .zero)
        calendar.headerHeight = 0
        return calendar
    }()

커스텀하면서 생긴 문제

처음에 헤더를 건드렸더니, 이렇게 일수가 잘리는 문제가 생겼습니다.

구글링을 했을 때, 생각보다 저와 비슷한 문제를 겪는 사람들이 꽤 있었고 그 중에서 이 분의 답변을 보게 되었습니다.

https://github.com/WenchaoD/FSCalendar/issues/655

첫번째 방법처럼 라이브러리 내 FScalendar.m 파일에서 이렇게 되어 있던 코드를
하단과 같이 바꿔주었습니다.

이 부분은 좀 더 찾아봐야 하는데, 내부에서 어떤 계산에 의해 높이가 리턴되다보니 제가 설정했던 높이 값이 안 들어가지 않았을까 싶네요. 위와 같이 변경을 하니, 높이가 잘리지 않고 잘 나타나는 것을 볼 수 있습니다.

마치면서

라이브러리 내부 코드에 주석들로 해당 코드들이 어떤 코드들인지 잘 정리되어 있어, 제 입맛대로 바꾸기 괜찮다고 생각이 들었습니다. 위와 같은 문제를 해결하는데 시간이 좀 걸렸지만 구현하면서 문제가 있다면 라이브러리 내 코드들을 잘 살펴보면서 사용하시면 괜찮을 것 같습니다.

FSCalendarAppearance.h 파일 내부 중

2개의 댓글

comment-user-thumbnail
2023년 9월 22일

안녕하세요 ! 혹시 FSCalendar 라이브러리 코드를 유저가 수정 가능한가요 ?

1개의 답글