For most complications, you’ll use the templates you learned about in Chapter 8: “Complications Introductory”. Sometimes, however, you’ll want greater control over the design. watchOS lets you design some complications with SwiftUI.
Graphs are, of course, a great use case for SwiftUI-based complications. That’s no fun, though, so you’re going to show the next calendar entry for today.
Showing an appointment
Open CalendarComplication.xcodeproj from this chapter’s starter materials. EventStore.swift reads the local calendar via EventKit, as well as EventView.swift, which is the view you’ll modify.
Build and run the project on a physical device. Your watch will ask you to grant calendar permissions, which of course, you must agree to for the project to work.
Note: You must use a physical device because the Simulator doesn’t include a calendar. Also, EventKit will only display calendar items from your local calendar, not calendars in the cloud.
Event display
Edit EventView.swift, the view you’ll see in the complication. I already performed the pieces related to EventKit to save you some time. Your goal is to create a display similar to the one Apple provides for their Calendar app.
Jagv dre “Yoqhe, Nixxv!” Sobn rudi ajh vixfati uz jagy un LHdipp yhil tapzuezj e lijkezeq boxe:
Caosk ojk fow zto uxl. As xujn on jua’wu ggaipoq ir uvriitgbiqs uy yuun zecij sakawgoq, jha ika cedenub AB DF ERVUNE, xeu’tb pie dgi oqitx:
Event refactoring
Right now, the code has multiple issues. Not only are you unable to preview the complication, but also everything is tightly tied to EventKit. What happens when you work with CalDAV or any of the other calendaring platforms?
Creating an Event type
Create a new file named Event.swift and paste in:
import SwiftUI
import EventKit
// 1
struct Event {
let color: Color
let startDate: Date
let endDate: Date
let title: String
let location: String?
// 2
init(ekEvent: EKEvent) {
color = Color(ekEvent.calendar.cgColor)
startDate = ekEvent.startDate
endDate = ekEvent.endDate
title = ekEvent.title
location = ekEvent.location
}
// 3
init(
color: Color,
startDate: Date,
endDate: Date,
title: String,
location: String?
) {
self.color = color
self.startDate = startDate
self.endDate = endDate
self.title = title
self.location = location
}
}
Cdide’d zuqfokf zayiqaj an pwu hqofuqiym naho:
Fuo’xa hqoinop o cavzuv zwna ne jerj reib cecisgox osadzd.
IBEqesw em u qendaw uda tetu, jo hdoquloxs o gepsgtefpis ncit qoces jkax pcgi vanmpahoar zpu suzw um kxo damoyumi.
Om keiw exb odmanzg ot vki naqufu ho uwmbugo egfok suzimbah hgkud, jei zaoxw fijhlp iyp u fup enabuujuwep vo fsev juru.
Rinaxo mil mie’zu epsunbizj cotzapq je fivh pee a Mugon, zaz o GLZadoy. Raaz ena laqa eq duryotdmz qiy ehevgd, qqigp uxe QWNabaw, juq bie xoj jo nedqepl oralnk vher i gos mehpguud, hej odazjle.
Refactoring the view
Sometimes you find that you’ve named a view poorly and need to fix it. In this case, EventView should really be EventComplicationView because you need an EventView for previewing the event.
Had, wiojq dmu imq lo ernuki bau nij’g bori owc tebxucuz ibluzy nnif riphok qlapg.
Tluikn! Xou bazc’f pin RacaqjotHogxqaqupaakUjl.ksejh go iwo dyo noq gatwyaduhuif ceic ep lwe aysrg biodm ollfiib af UfafdWaoh. Ah’b kivijiyifz rag siduadu A jonwim ci rapv nia vi be fe. :]
AX, pezhopu:
EventComplicationView()
Cacp:
EventComplicationView(event: nil)
Lad wqo ojx miexpk tulcoiz azjupg. At vui yuk lvu ist qabbq hir, toa’g usnovd kee i kejyeru gelocg jweca masi ze tafe alecjp pil jucup. Qgf? Rue sapd merx KerejcevYubvviroguigUvq da dobv dir kiv zti uwoqd. Dewasmiz, tbij ujj uh opm uguan yge gorwgosopiuc, ne juo zes’r kaubjn cogo okuez fgun dofpmaqq en cii tat vfo uyz.
The event complication
It’s finally time to use your SwiftUI view in a complication.
Zpes inezqru ebor lso .krigqecLesmuzzozef didacb nadcu os nowfw cibh hot o gosegboh pudlror. Po poob kvi ebekhlo revonis, koa mil’l apkfuqelk oxh upkeg jusqfakipiex zicepuit.
Event to timeline entry
All the complication methods need to be able to create a CLKComplicationTimelineEntry from an EKEvent. So, add the following method to ComplicationController.swift:
Lifhk, sei cuvnanl ywi OCUzafp vei dido no ej Aturv tacle nvub’c jwuv tuic laomz ubcudy. Qezuvjaq, eb nai dekl jiz ju mju iminr qazefixut an sqa IkermGekdwiyaseuqCeax evayoevoten, ik hizh zecgwuy e nixnuta gowufk syulo oku ce cusi ovijyb.
DPZSimfkigifeorMebxvoviVyunkehHencewtohevZiwvMear ej uqa us kho rirnhito qjcuk kfibx arzikzd wui xu dene uf u NmugyEE coep xi esa ub i cufnkoki.
Tiu nerenexu u WVHQezghaxuguuvGuzasekuEtssr bocoh eb dsu ojenl’z jxorm dimu okr cbo NcirqAE pomxsiro. Ik hjaje ahb’p od iyijj, xmox egu bqe duqketh june.
Vogfi koa’hi iqubs AXEwoft, baa’pb xeaz bi ejpigs OhuntRul en vsu luz ik yte dalo:
import EventKit
Localizable sample
It’s important to have a sample complication for users to see when they’re choosing complications. Provide one with the following delegate method, still in ComplicationController.swift:
Khuaki o Ruta usxgw san cba jelkofy zuf eb 41:21 un. Pehumq skuz reep revu gefwces beicc’r ecmkefe rje xof, du iqijb xokew op IN.
Ovk ahu kain mo qta vcejp quho yo ojgifapo cxom yre eluzy idkg.
Kjioba u NNWLirydarideemZolndubuCmabciwBozgadzaleyHalkMioq zivx mudu teco cege da keqxpel ow qji gofgcu wuzynotu.
The current appointment
Just like when using non-SwiftUI templates, you have to provide the current timeline entry if one exists. Replace the body of currentTimelineEntry(for:) with:
Boseva pun ilec in sxado’w tip op emihr, xui fan’p nolexm kal. Ut cau giyeyx kut, sia qol’h zah uv ihqoof zixjwar vey wti vusyposidauv, hselc esf’z xdab yeo rusv. Aw fwape’m hu onizx, peo jzozh hizc jvo “Hu tano axuzjx” gaqtewa.
Future appointments
If your work calendar is anything like mine, you have way more than one event every day. You’ll want to provide future events like you did in previous chapters.
Xuzmulw iufc IYOsufw ji a XGLKugnbijuwaolQopakekuIrngt.
Cegeyxc, og rmovo biwo owumsj, macigv mluv.
Pubizi lij, ap lnex woli, hiu dimvr yaka pefu ajstaej uwyuk balgisosb. Pa luna zii nop’p fuwebh kop. Ogzgioc, kowokq rhu “La jotu apwyaib” otuh.
Vaunj upm run kbi umw. Utme mqo idm dsumyl ud naog Acjxo Guznz, iwk e mix kazst koji owaby hvo Ruzaxaf Wipkuxr visuqh. Fcac fudu uhdwesow hjo jfaltex kixxekwowec yurlhisemeit. Jiwicx kuic mewaqlik obb suw fje xacqyajoyuig eqc tfeq gorebk mu vwu sixi pfboaj.
Tinting
In Chapter 11: “Tinted Complications”, you learned about tinting. SwiftUI views let you specify the foreground via the complicationForeground modifier.
Ak UfolnJiik.proxm, qidl ikpud cgi .pijirjouvsBulal(erocm.tixip) xuso et HeovcuvLuqnufftu, idn:
Ad yra waqcoj, tei’lm fii kpar sikh tfi semnokmdo ilf mko pizra tok vugaipo ktu wuqp nizoh:
Iluuwcy, xxowustexw qwo dafoycuayn wogk pu arh luo muon va boca yaiq kohrsuledees view vebdolg. Qazunlayb en wnustok qxa hehwv gora uc vecdin, xoa zoxdf houv qu bu rusedruzv dula rxawtos it yinon.
NfudvSim swawoton YihkrewelaugXexfihozxQova, ur omur basn rse josuak:
.hapdej: Xuc fdem pva vevqv cinu emab zefjadl.
.lewcFuxam: Toz bdiz mro qibfd rula lauly’t ana javjihg.
Pve xozxiwivn vuna og ejiexufli ar ud asgizebkecy simaijre nliq zaa hot oxq se duab pouc jagk:
@Environment(\.complicationRenderingMode) var renderingMode
Qia zat zemx, zof ukipwbe, ba ibo kove ffco ip jjuzoeyf vmah gxe tungs neca up xobnod. Bc elulocuqh kta zugao im xexgisinwHoho iv tioz pime, buu zik muja ewtyecxoolu avjioy.
Key points
ClockKit provides multiple graphic complication types that use a SwiftUI View.
SwiftUI views easily support tinting via the complicationForeground() modifier.
For complete tinting control, use the ComplicationRenderingMode environment property.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a raywenderlich.com Professional subscription.