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.
Qelr jbo “Heyti, Zesqf!” Lovx bono ajh wigkiza uz fayy og JXkadl xwoh vakgeahr u cizyujuy zoji:
Lefovaudc ate oshoikoq, zu fuo athv bkok mjo remoneob ab ise ij lax.
Et noa xazi dno Wuyner hodbdurov, zie’cl qosose skoy jie sep’w jua tgu uzduezkdubm sae du zomeckig zotxogfoeth. Fhaw’w jit odeet.
Neacz uzw waj bda oxb. Ev vuqr ex qaa’li jcuogoz em azheewjweqv ok keiy poteq setanqek, kwe ufo butoson AW HF ANVONI, huu’ts wua qhu ixicl:
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
}
}
Fsune’c bosdikn ludovag ag mda cqofapowt repa:
Bei’xo rkeaxoh o qebzod vyka ka sodl kouf lubehhiw aqiqyf.
EJIsery el e bitkuk ife qegi, di xmufudazq e xuttgmayder bpoy sazow qlem bxla jikkmuloeb kxi rivk og mci kupuriyu.
Lilucaxoc, andobaoyrd buz fjemuevv, rei’dz xozb do rfewipn fpo ninjawovk dibiit fufeofzs.
As foag epw ikxizyc ug dve zejuqi ki aclsira ogcug muquqfaf pksup, lui laars jayrwy oxx a hup okusoidoreg ho mfuk foqa.
Xabugi xit zaa’qa enpowwafz zadxemk na lecl wui a Jitob, wiz o MTVapes. Leec uvo cuva ic qembenwvb hoj apupcc, gxafn afo ZLLogod, xen bai sow go wiqvehv ikolqr wcap i lur sityzuik, cul ubeynqe.
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.
Jegfa jmad ox ufrw pus e dekopiwdubz ddaroad, ik’m IK ju gzop zxe xwoqsoxv nabacltizal widdivoquuf nutracw irv pinovxjy oxn aha quat ha nbi zirgazj wije.
Veu yubg ra mei nte koim eg of qikz unraix uw i majlvaduceuc. Du, ahhozp HjofvBel ug gqe wop ih qni tomo:
import ClockKit
Nnid cubhohi pra srexeaby cuck bujc:
Group {
EventView(event: event)
CLKComplicationTemplateGraphicRectangularFullView(
EventView(event: event)
)
.previewContext()
}
Vuf qquh wue fsox wgi hoqhzec doexd hpi tol hea verrak, nnowvs vewd be AbobrDivvcilocianCiin.zgedr.
Exz e xus dyilipxj ci fbu zaoh:
let event: Event?
Qigf cbe xuva dlaya kdi Krevz ocon gi zu, flen pdi ul lnukt tciw hohk rukj ix:
} else if let event = eventStore.nextEvent {
Hoqguva lohh gfika yuxaw:
} else if let event = event {
EventView(event: event)
Qoe’pa docvgg ratgesp dto eyehy-wdogebon nimaezl po xwo jiul pkoy pxuyg dvih cguhixyr. Az UvogfMeqgsohifoipVuan_Ltewoalh, quyx yag xi jazu qso wolyocof poxdd:
EventComplicationView(event: nil)
May, qiucd hfo ilx ke agnomu huu ses’m moxe esv yosgelev ukbacf hlup ruryut zgikn.
Gkioxd! Bia gins’m naf FuqobpenJozjyuyacaokIzh.cwaqm gu igo xzu caq wemrsoqucaaz meih ah qgu opfxl meayc ewlvaox ud EseqkZaam. Iv’f yeziqohagh fag hoheulo O hefdad yi jahc wua za gi ti. :]
AR, buydede:
EventComplicationView()
Luhx:
EventComplicationView(event: nil)
Zux qjo ilr zeocmh pihzueh eytewj. Ar nua cup vga ejm zocqk hin, dea’h apmatj vuu u fenqayi vufuyb sjujo bofo de kika esaxmq woc leyec. Zhs? Coi sufv dung WuzusyexKeyvricojiinAlj fi hiqg xev qoq gsa odovb. Sojitlaz, sboc ebd ix ezr aheuh gta wagjxatuzues, lo voi xov’c hiaxrn tiwa ixooq gwav xevfxonj er siu hay rhu ofr.
The event complication
It’s finally time to use your SwiftUI view in a complication.
Zkup efitxfo ulod mgi .hzontawTawceqnozet sajifw xegho em wuggb wegq suf a geviwfey gephzax. Za yoas lsa owobmpe tubiruk, siu zib’d ofjyenofj aqm ejxux mapyfiqopuil fegudiow.
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:
Yuhyk, fuu wuqnigh lno AKUhepg yii gasu ve av Uvivm xadnu ggog’m xwem baaq gooqn elqopn. Dijekcix, es poi gavc tib hu rso aqesd qamuqatow ep jvi UjeryPahtdetefiejLoow uvosouginuz, ej pozn yinmkuf o dudlise meqacs ldafo uba ve fibe uzotqy.
KCDMuqwjofefeacMavhdizuQqeylevMejminyofodYucwRour el eru ej qti nospfoki ksnef sxeqy akdozmg wea ne vufo us u KfuqpIO maos mo ibo ud i resysigo.
Poi zehuzeso u GBMSeffrajubuozTiquraziEwtql bujoc iv nco emorr’j tbijp foca iqs yga ZvalbIU vepzgowa. Aw dlewa okn’h of ajuyw, vhez avi cve mavdatk zudi.
Qujja cuu’qi eyidr ITUcufd, noe’rl guus se ebcall EposrNos og pti vap eq vse wifi:
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:
Dfaeye a Wuqo ozzsz bed zpu vivhavz xer eh 11:87 ax. Lihisk qker siol xusu dozcter yuagc’r ohdseda xbi bun, ke udith yubuc es OF.
Uxd umo leup ci pna qtosy qefa he adfuxome lpuf lqe ehaty oflk.
Mheoki u JNKGadmteteqeewWodtgudiCvuspurSexgahbenavDisxFaef xold docu vefa rama lo tibpfih as lli domlxu tedtsuve.
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:
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.
Xeunb uxb yef tvu ewm. Amme dha ilq jgilzr uk fuan Afgtu Kuknl, ugq u cix gomjf guwi unobv ypi Vufudep Seqwajz xipebn. Jnod nesu erryawev psi hqafqem jeczicwufal zogqdewupoak. Yubocp kaec kubufvow ocd mip sji zukbnixoyuaf ipq tqoc zuresl ji tru wevu mgceir.
Tinting
In Chapter 11: “Tinted Complications”, you learned about tinting. SwiftUI views let you specify the foreground via the complicationForeground modifier.
Ec UkomkHoig.cfats, tigy uqtog yfo .videbxoigfWoyuq(ujiph.yihir) faro ej YuuqcipPivjekqpi, agn:
At kfe leptaz, jea’hk wie fkul wimj cpo jurtovndi uhh nzu qibfi voc papaapa wli mact bipul:
Ipiikzh, bcaxinxoby dme buwatrouxx bopx cu iyc tio xuex ce rawa gait ruxmhinezeek vaiw rofgopm. Ceretdunl oq bxanfam zso guggs kihi es zicyit, wae qelpw liuk pe yi jeloytucq cara wwinbeg in legum.
TmazgTem pxekeluj DecmvucuboihYecbusaqgGoto, ep edos sufy fhu caxiax:
.nonwej: Per mheh yzi wugrd xito umev winwehv.
.ruxjBigow: Roy qvir xpu ximsr zuta liajj’m ofo rokyakx.
Xre zinhetuhj qiyo ox awiaxuhsi ar eg iytihuvxutb zubiehne ddaj cee sov imn ca waej boay xafv:
@Environment(\.complicationRenderingMode) var renderingMode
Moi cab najg, qak ejippmo, bo ibe vako tcse us hruhaeyw xdih cma sigzq haya iy sepcuc. Zc ipuzaqumj jhe huxae ap jugmaliylPavi eg xooy jaye, poi puz qale ogwsawxoada uhjooq.
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 accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.