iOS

iOS) FSCalendar의 속성 톺아보기(커스텀)

snowe 2021. 2. 21. 12:56

FSCalendar는 사용하는 사람들이 많은 만큼 사용하는 방법도 잘 나와있어 그 편리성 또한 장점중에 하나 인데요!

그걸 그대로 사용하면 좋지만 어느정도 입맛에 맞게 커스텀을 하려면 그래도 속성값에 대해서 정리되어있는? 곳이 있으면 좋겠더라구요

 

그래서 이번에 서비스 개발을 하면서 캘린더 커스텀을 할 때 공부했던 정보들을 공유하려 합니다.

 

기본적인 FSCalendar에서 바꿀 수 있는 속성들

func calendarStyle(){

	//언어 한국어로 변경
        calendarOrigin.locale = Locale(identifier: "ko_KR")
        
        
	//MARK: -상단 헤더 뷰 관련
        calendarOrigin.headerHeight = 66 // YYYY년 M월 표시부 영역 높이
        calendarOrigin.weekdayHeight = 41 // 날짜 표시부 행의 높이
        calendarOrigin.appearance.headerMinimumDissolvedAlpha = 0.0 //헤더 좌,우측 흐릿한 글씨 삭제
        calendarOrigin.appearance.headerDateFormat = "YYYY년 M월" //날짜(헤더) 표시 형식
                calendarOrigin.appearance.headerTitleColor = .black //2021년 1월(헤더) 색
        calendarOrigin.appearance.headerTitleFont = UIFont.systemFont(ofSize: 24) //타이틀 폰트 크기
       
       
	//MARK: -캘린더(날짜 부분) 관련
        calendarOrigin.backgroundColor = .white // 배경색
        calendarOrigin.appearance.weekdayTextColor = .black //요일(월,화,수..) 글씨 색
        calendarOrigin.appearance.selectionColor = .calendarSelectCircleGrey //선택 된 날의 동그라미 색
        calendarOrigin.appearance.titleWeekendColor = .black //주말 날짜 색
        calendarOrigin.appearance.titleDefaultColor = .black //기본 날짜 색
        
        
    	//MARK: -오늘 날짜(Today) 관련
        calendarOrigin.appearance.titleTodayColor = .seaweed //Today에 표시되는 특정 글자색
        calendarOrigin.appearance.todayColor = .clear //Today에 표시되는 선택 전 동그라미 색
        calendarOrigin.appearance.todaySelectionColor = .none  //Today에 표시되는 선택 후 동그라미 색
        
        
    	// Month 폰트 설정
        calendarOrigin.appearance.headerTitleFont = UIFont(name: "NotoSansCJKKR-Medium", size: 16)
        
        
        // day 폰트 설정
        calendarOrigin.appearance.titleFont = UIFont(name: "Roboto-Regular", size: 14)
}

 

달력 넘기기

FSCalendar에는 기본적으로 스와이프를 통한 달력 넘기기가 내장되어있습니다.

하지만 그 외에 별도의 버튼으로 넘기기를 원한다면 다음과 같이 구현할 수 있습니다.

	//MARK: -달력 < > 버튼 Action
    @IBAction func moveToNext(_ sender: Any) {
        self.moveCurrentPage(moveUp: true)
    }
    @IBAction func moveToPrev(_ sender: Any) {
        self.moveCurrentPage(moveUp: false)
    }
    
    
    //MARK: -사용자 정의 함수
    private func moveCurrentPage(moveUp: Bool) {
        dateComponents.month = moveUp ? 1 : -1
        self.currentPage = calendarCurrent.date(byAdding: dateComponents, to: self.currentPage ?? self.today)
        self.calendarOrigin.setCurrentPage(self.currentPage!, animated: true)
    }

 

이 때 유의 사항은 버튼의 hirachy를 달력 내부 혹은 달력 뒤쪽이 아니라 달력과 같은 계층에 위에 올려두어야 한다는 점 입니다.

이렇게!

 

주간 달력, 월간 달력

초기 셋팅

캘린더가 위치해있는 뷰에 height constraint를 주고 해당 값을 Outlet으로 선언해서 사용해야합니다!
class CalendarVC: UIViewController {

    @IBOutlet weak var calendarOrigin: FSCalendar!{
            didSet{
                calendarOrigin.delegate = self
            }
        }
    @IBOutlet weak var calendarHeight: NSLayoutConstraint!
}

extension CalendarVC : FSCalendarDelegate {
	
    // Calendar 주간, 월간 원활한 크기 변화를 위해
    func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool){
        calendarHeight.constant = bounds.height
        self.view.layoutIfNeeded ()
    }
}

주간, 월간 달력

self.calendarOrigin?.setScope(.month, animated: true) //월간 달력
self.calendarOrigin?.setScope(.week, animated: true) //주간 달력

 

캘린더 불러오면서 특정 날짜로 이동하기

만약 지정한 날짜가 현재 달에 없다면 촤라라라라랄락 하면서 그 날짜로 이동합니다

현재 달에 있다면 그냥 현재 화면에서 그 날짜가 선택된 상태!

let formatter = DateFormatter()
calendarOrigin.select(formatter.date(from: "2020-12-26"), scrollToDate: true)

 

날짜 선택/선택 해제 시 콜백 메소드

extension CalendarVC: FSCalendarDelegate{	

    // 날짜 선택 시 콜백 메소드
    func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
        formatter.dateFormat = "yyyy-MM-dd"
        print(formatter.string(from: date) + " 선택됨")
    }
    
    // 날짜 선택 해제 시 콜백 메소드
    public func calendar(_ calendar: FSCalendar, didDeselect date: Date, at monthPosition: FSCalendarMonthPosition) {
        keywordForCV = []
        print(formatter.string(from: date) + " 해제됨")
    }
}

 

 

이벤트 표시 Dot(Event Dot) 관련

초기 셋팅

class CalendarVC: UIViewController {

    @IBOutlet weak var calendarOrigin: FSCalendar!{
            didSet{
                calendarOrigin.delegate = self
                calendarOrigin.datasource = self
            }
        }
}

 

다음과 같이 배열을 선언하고 이벤트를 표시하고 싶은 날짜를 넣어놓습니다.

var eventsArray = [Date]()

 

이벤트를 표시하고자 하는데 원하는 카테고리가 두개일 경우(ex,안한 일: 초록색 & 한 일: 빨강색) 다음과 같이 분기처리하여 사용할 수 있음

   extension CalendarVC: FSCalendarDelegate, FSCalendarDataSource, FSCalendarDelegateAppearance{
      
      // 이벤트 밑에 Dot 표시 개수
      func calendar(_ calendar: FSCalendar, numberOfEventsFor date: Date) -> Int {
          if self.eventsArray.contains(date){
              return 1
          }
          if self.eventsArray_Done.contains(date){
              return 1
          }

          return 0
      }

      // Default Event Dot 색상 분기처리 - FSCalendarDelegateAppearance
      func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventDefaultColorsFor date: Date) -> [UIColor]?{
          if self.eventsArray.contains(date){
              return [UIColor.green]
          }

          if self.eventsArray_Done.contains(date){
              return [UIColor.red]
          }

          return nil
      }

      // Selected Event Dot 색상 분기처리 - FSCalendarDelegateAppearance
      func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventSelectionColorsFor date: Date) -> [UIColor]? {
          if self.eventsArray.contains(date){
              return [UIColor.green]
          }

          if self.eventsArray_Done.contains(date){
              return [UIColor.red]
          }

          return nil
      }
}

 

Event Dot의 크기를 줄이거나 위치를 조정하고싶다면?

다음과 같은 delegate에 있는 메소드를 통해 커스텀할 수 있습니다.

	// Event 표시 Dot 사이즈 조정
    func calendar(_ calendar: FSCalendar, willDisplay cell: FSCalendarCell, for date: Date, at monthPosition: FSCalendarMonthPosition) {
        let eventScaleFactor: CGFloat = 1.8
        cell.eventIndicator.transform = CGAffineTransform(scaleX: eventScaleFactor, y: eventScaleFactor)
    }
    
    func calendar(_ calendar: FSCalendar, appearance: FSCalendarAppearance, eventOffsetFor date: Date) -> CGPoint {
        return CGPoint(x: 0, y: 3)
    }

 

캘린더 날짜 선택 동그라미의 지름 커스텀

이건 혼자 헤메다가 찾게된건데 맞는 방법인지는 모르겠다..ㅎ

요기에 들어가서 다음과 같은 코드를 찾아봅시다

diameter가 지름이란 뜻인데 Pod를 열심히 파헤쳐보니 diameter가 그렇게 많지 않았어요!

그래서 하나씩 살펴보다가 이 부분이 날짜 선택 동그라미와 관련이 있다는 것을 알게 되었고, 저는 self.bounds.size.height*5.0/8.0 이 부분을 약간 수정하여 사용하였습니다!!

 

 

한 가지 주의해야 할 점은 아까 위에서 설명한 Dot의 사이즈 조절과 관련이 있다는 점 입니다.

아무래도 날짜 동그라미와 비율을 맞추어 이벤트 Dot의 크기가 결정되는 것 같습니다..!

따라서 이 부분의 크기를 줄였다면 Dot크기도 덩달아 같이 작아지므로 두 값을 잘 조절하여 사용해야 한다는 점 알려드립니다~

 

 

쓰다보니 좀 많아졌네요..그래도 도움이 되었으면 좋겠습니다! 좋은 하루 되세요~ :)