차근차근 커스텀 캘린더 #15
OneMoreThink
started this conversation in
Idea
Replies: 3 comments
-
|
우오아ㅏ아ㅏ아아아ㅏ아ㅏㅏㅏ 퇴마사👻 |
Beta Was this translation helpful? Give feedback.
0 replies
-
Beta Was this translation helpful? Give feedback.
0 replies
-
|
우와.. 파인 짱이에요!!!!!! |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment



Uh oh!
There was an error while loading. Please reload this page.
-
오늘도 안녕하신지요. 아임 파인입니다.
동료 러너의 캘린더의 귀신이 들렸다는 카톡을 받고
Kavsoft의 Custom Calendar 영상중 Calendar를 구성하는 부분만 빠르게 정리해보았습니다.
급하게 막 써내려가서 많은 타이포와 틀린 부분이 예상갑니다... ( 그래도 달력 정상적으로 뜬건 확인했습니다...)
영상의 흐름대로 정리해 나갔으니 혹시 달력을 사용중(또는 예정)이 시라면 '코드에 들린 귀신을 퇴치하는데' 조금이나마 도움이 되길 바랍니다.
(영상 일일이 따라치기 힘드니까 글 마지막에 소스코드만 모아놨습니다)
출처
Kavsoft
SwiftUI 3.0 Elegant Task App UI With Custom Date Picker - Custom Graphical Date Picker - Xcode 13
https://www.youtube.com/watch?v=UZI2dvLoPr8&t=650s
CustomCalendarHeader - 년도, 달, 화살표
CustomCalendarHeader - 요일 표시
days를 선언해서 요일을 나타내는 문자열을 넣어두고일수 띄우기
DateValuestruct 별도로 만들어 사용currentMonth를 이용해서 지정한 달의 날짜들을 가져오는 로직을 생성Date extension
DateValue
currentMonth와 extractDate()
LazyVGrid를 사용해서 달력 일수 띄우기
여기까지 왔을 때 이상한점 : 달을 기준으로 1일부터 해당달에 있는 일수만큼 나와야하는데 현재 날짜를 기준으로 형성됨 ( 오늘 날짜 16일 )
GPT Wal
시간 구성 요소의 문제점
Date 객체는 내부적으로 시간도 포함하고 있기 때문에, 단순히 날짜(년, 월, 일)만을 고려하여 계산할 때 다음과 같은 문제가 발생할 수 있습니다:
첫 날 계산 로직의 필요성
위에서 언급한 문제들을 피하기 위해, 월의 첫 날을 계산할 때는 다음과 같은 로직을 사용합니다:
달력의 시작 날짜를 1로 맞추도록 getAllDates 변경
달력의 화살표를 누르면 currentMonth를 수정하는 로직 포함시키기
onChange()를 사용 currentMonth 값이 변경될때마다 getCurrentMonth를 이용해 해당 달에 대한 Date 값 가져와서 현재 날짜인 currentDate 값을 업데이트// 현재 Month(ex: 4월에 currentMonth 값을 더해서) 지정한 달의 Date 값 가져오기 func getCurrentMonth() -> Date { // 현재 날짜가져오기 let calendar = Calendar.current // 가져온 현재 날짜에서 달(.month)에 currentMonth 값을 더하고 이를 Date 타입으로 반환 guard let currentMonth = calendar.date(byAdding: .month, value: self.currentMonth, to: Date()) else { return Date() } return currentMonth } // 현재날짜에서 @State currentMonth 값을 이용해 달을 바꾸고 // 달이 바뀌면 해당 달에 대한 날짜들을 반환함 (앞서 만든 DateValue라는 타입으로) func extractDate() -> [DateValue]{ // 현재 날짜가져오기 let calendar = Calendar.current // 가져온 현재 날짜에서 달(.month)에 currentMonth 값을 더하고 이를 Date 타입으로 반환 // getCurrentMonth() 따로 만들었으므로 이를 이용해서 원하는 달에 대한 Date 값을 얻어옴 let currentMonth = getCurrentMonth() // 앞서 Date extension 을 사용 ( Date 타입으로 반환했기 때문에 사용가능) // 앞서 현재 달 + currentMonth(이것에 값을 바꾸면서 달을 바꿈) 을 통해 원하는 달을 구하고 // 해당 달의 일들을 구함 return currentMonth.getAllDates().compactMap { date -> DateValue in // 이때 getAllDates()에서 반환된 Date 배열의 요소들에서 날짜를 추출해서 let day = calendar.component(.day, from: date) // 앞서 우리가 만든 DateValue type에 넣어줌 return DateValue(day: day, date: date) } }// Date를 원하는 형태로 보여주기 위해 포멧팅해줌 func extraDate()->[String]{ // Date를 원하는 형태로 바꿔주는 formatter 만들기 let formatter = DateFormatter() // 만든 formatter에 원하는 형식 지정해주기 formatter.dateFormat = "YYYY MMMM" // 현재 currentDate(Date)에 위에서 만든 formatter를 적용해서 반환 let date = formatter.string(from: currentDate) return date.components(separatedBy: " ") }여기까지 왔을 때 날짜와 요일이 맞지 않는 현상이 보임
주어진 달의 날짜와 요일을 맞추기위해 달에 맞는 날짜들을 반환하는 extractDate()와 일수를 처리하는 Date extension의 getAllDates 수정
@ViewBuilder 사용
// 조건에 따라 날짜를 표시할지 안할지를 결정하기 위해 @ViewBuilder 사용 // -1 (이번달에 포함이 안되는 날짜의 경우에)는 화면을 그릴 때 제외 @ViewBuilder func CardView(value: DateValue) -> some View { VStack { if value.day != -1 { Text("\(value.day)") .font(.title3.bold()) } } .padding(.vertical, 8) .frame(height: 60, alignment: .top) }Beta Was this translation helpful? Give feedback.
All reactions