WidgetKit (15)
이렇게 SwiftCal 앱의 LockScreen을 디자인한다.
이번에 적용할 프로젝트는 CoreData Version으로 된 걸 사용했다.
EntryView를 각 Case 별로 분류
우선 환경변수 @Environment(\.widgetFamily) var family
를 만들어 준다.
Widget의 Supported Family 수정
LockScreen의 위젯을 지원해야 하므로
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
struct SwiftCalWidget: Widget {
let kind: String = "SwiftCalWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
// 생략
}
.configurationDisplayName("Swift Study Calendar")
.description("Track days you study Swift with streaks.")
.supportedFamilies([.systemMedium,
.accessoryRectangular,
.accessoryInline,
.accessoryCircular])
}
}
이렇게 추가를 해준다.
MediumCalendarView 만들기
Widget 밑에 새로
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
private struct MediumCalendarView: View {
var entry: CalendarEntry
let columns = Array(repeating: GridItem(.flexible()), count: 7)
var streakValue: Int
var body: some View {
HStack {
Link(destination: URL(string: "streak")!) {
VStack {
Text("\(streakValue)") // modified
// 생략
}
}
Link(destination: URL(string: "calendar")!) {
VStack {
CalendarHeaderView(font: .caption)
LazyVGrid(columns: columns, spacing: 7) {
// 생략
}
}
}
.padding(.leading, 6)
}
.padding()
}
}
위와 같이 필요한 View를 만들어준다. 이유는 각 case 별로 view를 나눌때 조금 더 EntryView의 코드를 간결하게 하기 위함이다.
LockScreenCircularView 만들기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private struct LockScreenCircularView: View {
var entry: CalendarEntry
var currentCalendarDays: Int {
entry.days.filter { $0.date?.monthInt == Date().monthInt }.count
}
var daysStudied: Int {
entry.days.filter { $0.date?.monthInt == Date().monthInt }.filter { $0.didStudy }.count
}
var body: some View {
Gauge(value: Double(daysStudied), in: 1...Double(currentCalendarDays)) {
Image(systemName: "swift")
} currentValueLabel: {
Text("15")
}
.gaugeStyle(.accessoryCircular)
}
}
Circular 특성을 활용한 Gauge 스타일은 진행 상황(예: 학습일)을 시각적으로 표현하는 데 적합하다.
Docs에 설명이 잘 나와있으므로 읽어보는걸 추천.
LockScreenRectangularView 만들기
MediumCalendarView와 유사하다.
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
private struct LockScreenRectangularView: View {
var entry: CalendarEntry
let columns = Array(repeating: GridItem(.flexible()), count: 7)
var body: some View {
LazyVGrid(columns: columns, spacing: 4) {
ForEach(entry.days) { day in
if day.date!.monthInt != Date().monthInt {
Text(" ")
.font(.system(size: 7))
} else {
if day.didStudy {
Image(systemName: "swift")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 7, height: 7)
} else {
Text(day.date!.formatted(.dateTime.day()))
.font(.system(size: 7))
.frame(maxWidth: .infinity)
}
}
}
}
.padding()
}
}
Case 별 View 적용
테스트는 이렇게 8,9,10일을 공부했다고 가정하여 진행
inline
1
2
case .accessoryInline:
Label("Streak - \(calculateStreakValue()) days", systemImage: "swift")
Circular
1
2
case .accessoryCircular:
LockScreenCircularView(entry: entry)
Rectangular
1
2
case .accessoryRectangular:
LockScreenRectangularView(entry: entry)
Lock Screen 위젯에서 탭 이벤트 처리하기
1
2
3
case .accessoryInline:
Label("Streak - \(calculateStreakValue()) days", systemImage: "swift")
.widgetURL(URL(string: "streak"))
이미 SwiftCalApp.swift에서
1
2
3
.onOpenURL { url in
selectedTab = url.absoluteString == "calendar" ? 0 : 1
}
적용중이기에 inline 쪽을 클릭하면 streakView가 나오게 된다.
SwiftCal Lock Screen Padding (iOS 17)
LockScreenRectangularView의 LazyVGrid의 Padding을 지워주면 된다.
이로인해 Calender가 조금 더 확장되고 덜 비좁아지게 된다.
padding을 삭제한것으로 좌(before), 우(after) 화면에서의 Calendar의 차이가 극명하게 보이는걸 알 수 있다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.