티스토리 뷰

프로퍼티

private let calendar = Calendar.current
private let dateFormatter = DateFormatter()
private var calendarDate = Date()
private var days = [String]()

먼저 필요한 프로퍼티는 위와 같습니다.
하나씩 설명해 드릴게요!

  • calendar : Calendar 구조체를 사용하기 위하여 사용자의 현재 달력으로 초기화해놓은 프로퍼티입니다.
  • dateFormatter : 2022년 01월과 같은 형태로 타이틀을 만들어 주기 위한 DateFormatter입니다.
  • calendarDate : 달력에 표시될 날짜를 저장합니다. 이전 달이나 다음 달로 이동하게 되면 이동한 달이 포함된 날짜를 가지고 있습니다.
  • days : 달력에 날짜를 표시하기 위한 String 배열입니다. 1일이 화요일부터 시작된다면 ["", "", "1", "2"...]와 같은 형태로 저장이 됩니다.



메서드

필요한 메서드

  • configureCalendar() : 달력을 표시해주기 위하여 calendarDatedateFormmatter를 초기화합니다.
  • startDayOfTheWeek() -> Int : calendarDate가 해당하는 달의 1일이 시작되는 요일을 리턴합니다.
  • endDate() -> Int : calendarDate가 해당하는 달의 날짜 개수를 리턴합니다.
  • updateTitle() : titleLabel2022년 01월과 같이 년, 월을 업데이트합니다.
  • updateDays() : startDayOfTheWeek()endDate()를 이용하여 daysString 배열을 만들어 넣습니다.
  • updateCalendar() : 달력을 처음 띄우거나 달을 이동할 때 마다 updateTitle(), updateDate()를 호출합니다.
  • minusMonth() : calendarDate의 달을 이전 달로 변경합니다.
  • plusMonth() : calendarDate의 달을 다음 달로 변경합니다.

필요한 메서드는 위와 같습니다.
이제 하나하나 구현 해볼게요!

 

configureCalendar()

let components = self.calendar.dateComponents([.year, .month], from: Date())
self.calendarDate = self.calendar.date(from: components) ?? Date()

현재 날짜에서 년, 월만 뽑아냅니다. 2022년 1월 03일 17:41 이면 2022년 1년만 뽑아내는 거죠!
년, 월만 뽑아낸 DateComponents 타입을 date(from:)을 이용하여 Date 타입으로 바꿔주고 calendarDate에 저장합니다.

self.dateFormatter.dateFormat = "yyyy년 MM월"

dateFormatter 도 원하는 포맷으로 설정해줍니다.
저는 2022년 01월과 같이 표시하고 싶어서 yyyy년 MM월로 설정해줬어요!

 

startDayOfTheWeek() -> Int

return self.calendar.component(.weekday, from: self.calendarDate) - 1

component()를 이용하여 1일이 시작하는 요일을 계산하면 1은 일요일, 7은 토요일로 반환이 됩니다.
days 배열의 0번 인덱스를 일요일로 표시해주기 위하여 -1 을 해준 후 반환합니다.

2022년 1월은 1일이 토요일부터 시작이니 6이 반환되겠네요.

 

endDate() -> Int

return self.calendar.range(of: .day, in: .month, for: self.calendarDate)?.count ?? Int()

range(of:, in:, for:)를 이용하여 calendarDate가 해당하는 달의 날짜가 며칠까지 있는지 계산하여 반환합니다.
2022년 1월은 31일까지 있으니 31이 반환되겠죠?

 

updateTitle()

let date = self.dateFormatter.string(from: self.calendarDate)
self.titleLabel.text = date

dateFormmater를 이용하여 calendarDate를 설정해놓은 포맷으로 만들어준 후 타이틀에 적용시킵니다.

 

updateDays()

self.days.removeAll()
let startDayOfTheWeek = self.startDayOfTheWeek()
let totalDays = startDayOfTheWeek + self.endDate()

updateDays()가 불렸을 때 이전의 데이터는 필요 없어지기 때문에 days를 비워줍니다.
startDayOfTheWeek에 요일의 시작 인덱스를 저장해주고 totalDays에 시작 인덱스와 날짜 개수를 더해서 넣어줍니다.

2022년 1월은 1일이 토요일이니까 6, 총 31일까지 있으니 31. 따라서 totalDays에 37이 저장됩니다.

for day in Int()..<totalDays {
    if day < startDayOfTheWeek {
        self.days.append("")
        continue
    }
    self.days.append("\(day - startDayOfTheWeek + 1)")
}

0부터 36까지 총 37번 동안 for문을 돌면서 days에 문자열을 넣어줍니다.
for문 안의 코드를 자세히 보겠습니다.

if day < startDayOfTheWeek {
    self.days.append(String())
    continue
}

daystartDayOfTheWeek 보다 작으면 days에 빈 문자열을 넣어줍니다.
즉, 1일이 시작하는 요일의 인덱스 전까지 빈 문자열을 넣는 겁니다.

2022년 1월 기준으로 days["", "", "", "", "", ""]가 들어가겠네요.

self.days.append("\(day - startDayOfTheWeek + 1)")

day가 6이 되면 if문에 걸리지 않겠네요. 6번 인덱스부터 1부터 31까지의 숫자가 들어갑니다.
day가 6일 때 startDayOfTheWeek이 6이니까 1이 들어가게 되고,
day가 7일 때 2, day가 8일 때 3... 이 들어가게 됩니다.

for문이 끝나면 days의 값이 ["", "", "", "", "", "", "1", "2", "3", "4", ... "31"]로 업데이트됩니다.

self.collectionView.reloadData()

메서드 마지막에 reloadData()를 불러 바뀐 days에 맞게 collectionView를 업데이트하도록 해줍니다.

 

updateCalendar()

self.updateTitle()
self.updateDays()

타이틀과 날짜를 업데이트해주는 메서드를 불러줍니다.

private func configureCalendar() {
    let components = self.calendar.dateComponents([.year, .month], from: Date())
    self.calendarDate = self.calendar.date(from: components) ?? Date()
    self.dateFormatter.dateFormat = "yyyy년 MM월"
    self.updateCalendar()
}

아까 작성한 configureCalendar()에서 updateCalendar()를 불러주겠습니다.

여기까지 작성하고 실행해주면 위의 사진과 같이 타이틀에 년, 월 정보가 표시되는 것을 볼 수 있습니다.
날짜 부분의 업데이트는 Calendar 구조체로 달력 구현하기 (4)에서 다루겠습니다!

 

minusMonth()

self.calendarDate = self.calendar.date(byAdding: DateComponents(month: -1), to: self.calendarDate) ?? Date()
self.updateCalendar()

date(byAdding:, to:)를 이용해서 -1 연산을 해준 후 updateCalendar()를 불러줍니다.

 

plusMonth()

self.calendarDate = self.calendar.date(byAdding: DateComponents(month: 1), to: self.calendarDate) ?? Date()
self.updateCalendar()

minusMonth()와 같은 메서드를 이용하여 +1 연산을 해줍니다.

달력 구현을 위한 메서드 구현이 끝났습니다.
구현한 메서드를 이용하여 날짜를 표시해주고, 버튼을 설정하는 과정은 다음 글에서 다루겠습니다.

 


 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함