【SwiftUI】잔디 달력 만들었다
MMHeatmap 라이브러리
절각 라이브러리를 만들었으므로 학습도 겸해 Swift Package Manager에 대응해 공개해 보았습니다.
도입 방법이라든가 리포지토리의 README.md에 있으므로 생략합니다.
View 구조
최하층부터 순서대로 설명합니다.
일주일용 VStack
우선 1주간분(7개의 셀)을 다음과 같은 느낌으로 VStack으로 세로로 늘어놓습니다.
VStack(spacing:2){
ForEach(0..<7){ i in
RoundedRectangle(cornerRadius: 2).frame(width: 10,height: 10).modifier(CellColorModifier(isRange: (i >= start && i <= end ) , value: values[i], maxValue: maxValue,minColor: style.minCellColor,baseColor: style.baseCellColor))
}
}
MMHeatmapColumnView.swift
미리보기하기 어렵기 때문에 이 계층에서는 Date 형은 취급하지 않고, 위의 View 로부터 주어진 표시 범위와 값에 따라 셀의 색을 결정합니다.
※CellColorModifier에 대해서는 후술합니다.
1개월용 HStack
그런 다음 HStack에서 일주일 동안 VStack을 일주일 동안 정렬합니다.
1개월분의 주수의 특정은, 다음 달의 0일(즉 그 달의 마지막 날)을 설정한 DateComponents를 Date형으로 한 후, Calendar로 주수를 요구할 수 있습니다.
var comp = DateComponents()
comp.year = 2021
comp.month = MM + 1
comp.day = 0
let date = calendar.date(from: comp)!
let weeks = calendar.component(.weekOfMonth, from: date)
몇 달 동안 HStack
마지막으로 1개월용 HStack을 지정 범위의 월수분 늘어놓습니다.
셀의 색 결정
데이터가 되는 수치 배열중에서 최대치의 색을 baseColor, 최소치 0의 색을 minColor로서 baseColor와 minColor의 중간색을 구합니다.
또한, 데이터의 값을 nil로 했을 경우는 셀의 색을 투명(Color.clear)으로 설정하고 있습니다.
다음 수정자
saturation = (saturation - secondSaturation) * pct + secondSaturation
brightness = (brightness - secondBrightness) * pct + secondBrightness
의 부분에서 중간색(채도, 명도)을 결정하고 있습니다.
(이 코드는 색조의 중간 색을 요구하지 않았습니다.)
fileprivate struct CellColorModifier:ViewModifier {
init(isRange:Bool,value:Int?,maxValue:Int,minColor:UIColor,baseColor:UIColor) {
self.isRange = isRange
if let v = value{
let pct:CGFloat = CGFloat(v) / CGFloat(maxValue)
var secondHue:CGFloat = 0
var secondSaturation:CGFloat = 0
var secondBrightness:CGFloat = 0
var secondAlpa:CGFloat = 0
minColor.getHue(&secondHue, saturation: &secondSaturation, brightness: &secondBrightness, alpha: &secondAlpa)
var hue:CGFloat = 0
var saturation:CGFloat = 0
var brightness:CGFloat = 0
var alpha:CGFloat = 0
baseColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
saturation = (saturation - secondSaturation) * pct + secondSaturation
brightness = (brightness - secondBrightness) * pct + secondBrightness
self.rangeColor = Color(UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha))
}else{
self.rangeColor = Color(UIColor.clear)
}
}
let isRange:Bool
let rangeColor:Color
func body(content: Content) -> some View {
Group{
if(isRange){
content.foregroundColor(rangeColor)
}else{
content.foregroundColor(Color.clear)
}
}
}
}
Swift Package
다음 기사를 참고했습니다. jjjkkkjjj님께 감사드립니다.
htps : // 이 m / j j k j / ms / 727517263292 Ae 7 A 3 A 87
덧붙여서 SwiftUI의 미리보기를 할 때에 대량의 에러가 나오는 경우는, 미리 보기하는 파일 이외를 닫아 가상 단말을 Mac로부터 iPhone이나 iPad로 했다고 고쳤습니다.
끝에
이상으로 기본적인 잔디 달력을 만들 수 있었습니다.
개선할 의욕이 생기면 GeometryReader를 사용하여 MMHeatmap을 화면 크기에 맞는 캘린더로 개선하고 싶습니다.
Reference
이 문제에 관하여(【SwiftUI】잔디 달력 만들었다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ttttpzm/items/4d389359e7cc521558c5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
VStack(spacing:2){
ForEach(0..<7){ i in
RoundedRectangle(cornerRadius: 2).frame(width: 10,height: 10).modifier(CellColorModifier(isRange: (i >= start && i <= end ) , value: values[i], maxValue: maxValue,minColor: style.minCellColor,baseColor: style.baseCellColor))
}
}
var comp = DateComponents()
comp.year = 2021
comp.month = MM + 1
comp.day = 0
let date = calendar.date(from: comp)!
let weeks = calendar.component(.weekOfMonth, from: date)
데이터가 되는 수치 배열중에서 최대치의 색을 baseColor, 최소치 0의 색을 minColor로서 baseColor와 minColor의 중간색을 구합니다.
또한, 데이터의 값을 nil로 했을 경우는 셀의 색을 투명(Color.clear)으로 설정하고 있습니다.
다음 수정자
saturation = (saturation - secondSaturation) * pct + secondSaturation
brightness = (brightness - secondBrightness) * pct + secondBrightness
의 부분에서 중간색(채도, 명도)을 결정하고 있습니다.
(이 코드는 색조의 중간 색을 요구하지 않았습니다.)
fileprivate struct CellColorModifier:ViewModifier {
init(isRange:Bool,value:Int?,maxValue:Int,minColor:UIColor,baseColor:UIColor) {
self.isRange = isRange
if let v = value{
let pct:CGFloat = CGFloat(v) / CGFloat(maxValue)
var secondHue:CGFloat = 0
var secondSaturation:CGFloat = 0
var secondBrightness:CGFloat = 0
var secondAlpa:CGFloat = 0
minColor.getHue(&secondHue, saturation: &secondSaturation, brightness: &secondBrightness, alpha: &secondAlpa)
var hue:CGFloat = 0
var saturation:CGFloat = 0
var brightness:CGFloat = 0
var alpha:CGFloat = 0
baseColor.getHue(&hue, saturation: &saturation, brightness: &brightness, alpha: &alpha)
saturation = (saturation - secondSaturation) * pct + secondSaturation
brightness = (brightness - secondBrightness) * pct + secondBrightness
self.rangeColor = Color(UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: alpha))
}else{
self.rangeColor = Color(UIColor.clear)
}
}
let isRange:Bool
let rangeColor:Color
func body(content: Content) -> some View {
Group{
if(isRange){
content.foregroundColor(rangeColor)
}else{
content.foregroundColor(Color.clear)
}
}
}
}
Swift Package
다음 기사를 참고했습니다. jjjkkkjjj님께 감사드립니다.
htps : // 이 m / j j k j / ms / 727517263292 Ae 7 A 3 A 87
덧붙여서 SwiftUI의 미리보기를 할 때에 대량의 에러가 나오는 경우는, 미리 보기하는 파일 이외를 닫아 가상 단말을 Mac로부터 iPhone이나 iPad로 했다고 고쳤습니다.
끝에
이상으로 기본적인 잔디 달력을 만들 수 있었습니다.
개선할 의욕이 생기면 GeometryReader를 사용하여 MMHeatmap을 화면 크기에 맞는 캘린더로 개선하고 싶습니다.
Reference
이 문제에 관하여(【SwiftUI】잔디 달력 만들었다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ttttpzm/items/4d389359e7cc521558c5
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
이상으로 기본적인 잔디 달력을 만들 수 있었습니다.
개선할 의욕이 생기면 GeometryReader를 사용하여 MMHeatmap을 화면 크기에 맞는 캘린더로 개선하고 싶습니다.
Reference
이 문제에 관하여(【SwiftUI】잔디 달력 만들었다), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ttttpzm/items/4d389359e7cc521558c5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)