티스토리 뷰
프로퍼티
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()
: 달력을 표시해주기 위하여calendarDate
와dateFormmatter
를 초기화합니다.startDayOfTheWeek() -> Int
:calendarDate
가 해당하는 달의 1일이 시작되는 요일을 리턴합니다.endDate() -> Int
:calendarDate
가 해당하는 달의 날짜 개수를 리턴합니다.updateTitle()
:titleLabel
에2022년 01월
과 같이 년, 월을 업데이트합니다.updateDays()
:startDayOfTheWeek()
과endDate()
를 이용하여days
에String
배열을 만들어 넣습니다.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
}
day
가 startDayOfTheWeek
보다 작으면 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 연산을 해줍니다.
달력 구현을 위한 메서드 구현이 끝났습니다.
구현한 메서드를 이용하여 날짜를 표시해주고, 버튼을 설정하는 과정은 다음 글에서 다루겠습니다.
'iOS' 카테고리의 다른 글
[iOS] iTunes Search API (2) | 2022.01.06 |
---|---|
[iOS] Calendar 구조체로 달력 구현하기 (4) - 달력 표시, 버튼 기능 구현하기 (2) | 2022.01.05 |
[iOS] Calendar 구조체로 달력 구현하기 (2) - 달력 뷰 구성하기 (0) | 2022.01.03 |
[iOS] Calendar 구조체로 달력 구현하기 (1) - Calendar 구조체 알아보기 (2) | 2021.12.11 |
[iOS] Storyboard 없이 ViewController 연결하기 (0) | 2021.07.09 |
- Total
- Today
- Yesterday
- calendar
- 에로토스테네스의 체
- Git
- 별졈
- iTunes Search API
- map
- BOJ
- 달력
- Kakao
- 최대공약수
- 최소공배수
- java
- programmers
- 깊이 우선 탐색
- DFS
- IOS
- TIL
- 유클리드 호제법
- sql
- SWIFT
- UISearchController
- 프로그래머스
- ternary
- abs()
- 다리를 지나는 트럭
- Algorithm
- compactMap
- Firebase
- mysql
- Baekjoon
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |