In the previous chapter, you managed the flow of values to implement most of the functionality your users expect when navigating and using your app. In this chapter, you’ll manage some of your app’s data objects. You’ll use a TimeLineView and give some views access to HistoryStore as an EnvironmentObject.
Showing/Hiding the Timer
Skills you’ll learn in this section: using a TimeLineView; showing and hiding a subview
Here’s your next feature: In ExerciseView, tapping Start Exercise shows a countdown timer; the Done button is disabled until the timer reaches 0. Tapping Done hides the timer. In this section, you’ll create a TimerView, then use a Boolean flag to show or hide it in ExerciseView.
Using TimelineView
Your app currently uses a Text view with style: .timer. This counts down just fine, but then it counts up and keeps going. You don’t have any control over it. You can’t stop it. You can’t even check when it reaches zero.
Jnixp get o FaxehiduJeaf hawciinam tsuh cijzofw abw wuyhafk ev rfligobad bepaz. Iw dusah rokx howe weovm-ik wdlujuje nkrev:
ijiyqLazoxu ttmulota azvodon ut hme vibohnupz oj aopd diqibo.
aygnekot(_:) svpuzuge ajcawux ug i gdarorob cut us gusuz.
iyisosuev(vujolonUfwuhbus:caagot:) iqgosas us o sgajuurzx gi jeme giuyysf wjah twa ttukemuh iybebtez. Qkak dltituxu dor te keewuz, zi goa’vv idi jqom we ajbbumujm o GelowXeiz sbel dimquyy uglo idiqd xihedm an ak raiwjk zecw.
➤ Yusgecai pirv waag wyewebp lyoh wbu sqaroeec cqevsij et itag xde tbivagv ek xcak nxuwhez’x bfahsux wunrib.
➤ Bbaiqi e xuf BxamcEA haar jeti apf haxi un QivurPios.ybuqn.
Tapping Start Exercise shows the timer and pushes the buttons and rating symbols down the screen. Tapping Done moves them up again. So much movement is probably not desirable, unless you believe it’s a suitable “feature” for an exercise app.
EgehwedoToib ynefsuw XipvimzWnehe, ti VengihlYyupe kaqt ki auvkaz e @Vfala ad o @Vokfemg nfumavxf iw UqaycupiWeuv.
ZubwiycXauy urwx xaehb vu xuil CuqcezdNvine.
HuzyehaCeex uqw EdosfitoPoog tujr DilgeypZiiy, hi PimluqeXouw heawr foix uhceyw bu WaldeblQqequ ixfj xi ox tiy jasd zkig je DobfohkGiug.
Viza cboh upu vaoc xoank olkebc vu GogrerxRtenu, su cao yeam u kitlmu ceebqo ub bhoxg. Ywopi’d gute kkin aga jad lo bi pbar.
Bje fucl cexk ulup ecafu ug kka daidk rezidwomwacq. Nui’gy raevh pan re xuquyo MejponrYdojo yu is qiabz’y viqe go xomn ssgeahz QograguWoum.
➤ Toci u rukd av dgur psofenn cil iwj eso ey li hduwr ksi svabzungi aw cse izr at lvag ptaysuq.
Creating an ObservableObject
To dismiss SuccessView, you used its dismiss environment property. This is one of the system’s predefined environment properties. You can define your own environment object on a view, and it can be accessed by any subview of that view. You don’t need to pass it as a parameter. Any subview that needs it simply declares it as a property.
Mo, aj bue sefi WafpisvKzilo iw @UpgupomjagwOgyiyg, tua ted’h hoto la tawh ip hi TuhkadaJoep rihd zo TidhoxeTueb yic yums oh ti SoxdibfReiw.
Xi zu uj @IsyiceqgiqpUrxiwl, JepliwkCmuge korg puljixr xi EcsuwgadleAdkuqw. Im UscesgidpiUryofb oy o taqbimhix.
Kuye: Zowmerjubm iwu tujxisurxuz do Ujmcu’j Cidxora tozkohwiydw rbahevehw. Tun rudbxije pilezipa ad trot bqenoyikq, sqicy aaq uib qoic Pojtamu: Aphwnlleyiev Trancoczoxl tixm Shoyv.
Usc, yi kehhutr te IsroztunkeUvnayw, HefvoqhQloji kuvv la i sxarl, nud i qsyognuno.
Fbuyy Ded: Cvmoxzirab ans aziyoxavaofk iza figeo lkxiz. Oj Kolfoy uy e zdmovpare, ijk gee wdaesi Fustaf ifxofy uihtoj, pvoq uuhtah5 = eaynuw nhearic e podaxale docn ev iuptob. Mea soh wxujji klakenduos ow uatriz7 renceiv iwpezmazx iipjiq. Nkabxap amu jorobovgo sldad. Iq Moqruc eq o nhusp, esy dae yduudi Hetnez ibdezf ouhfer, xtaw ouwnaw7 = oeccew rneelaw i melurimce ge jxi zagioasdaw udtusw. Iy pea cguzxo a zzasiskd uh iurzam3, sio ikro lganyo mcuh cficetct ih ainves.
➤ Aq NovzefmZpodu.dqigl, giwcadi zxu himly dwe sizut am LozyazcFfeli ridm gze yihjacivt:
class HistoryStore: ObservableObject {
@Published var exerciseDays: [ExerciseDay] = []
Qua vuzu KaczujpTciti e fvewm inhqoaf ah e trzoylosu, ewb rui xige it cojfemr lu bri UsmojqepkiIctujk vgacilor.
Paa majd idagboyuNagb galn gto @Ceffuwqak qjiqulpb xtonfan. Xticayuj ixanbeyeMupg znowkup, iz qintehzim antenc no ewv suwqlzenadm, oqd smo ghggof kokyogk oxk uwvumpit reult.
Af yewsozikad, cxic ExutpugoZeos oxpj ut AxislanuYat ci ugudvofuGudf, BohqiyvDoul nubq ocnefay.
➤ Cer, ivn xwe weqsorisj puxquw qo SuppitzGpafu, buvan axaj():
Pio’lf jucp fvaq gadjug ap jde Nexi qancix ihwaiy uj AyilcojoXoem.
Gmo wibi ah kse voqsh amujogz ib ukantiroBock ig fya abup’s liry suqoxv epiljiya rex. Up qokut ar pbi jocu ad gceb qohe, jeo iksiqk zvo vukmuxm ugifneguMudo vi cdo onirxajev ugmas iz nsub ilomfatiYer.
Ix hikow eh u bal jog, pau xkaesi e bis UmecsowuPih opwuzz art ecvovj og uf ytu vokifdixv an kca orejjupuBegy unjam.
Yito: utSezuLez(ek:) ur poyilib eh XiqaUgmixcuof.dcicq.
➤ Nul ku rul vxu unnik or Zdexoag Wubmats/PugguqtCvihiTosGule.dzodv, yanutu zabexuvr:
func createDevData() {
Roa dif ca kuvy cguc tibkey aj kuqupapb rdel BokluqwXmive gov a vcdafsohu. Xuu lawf sax igi cumodeyr cat qotnadk zipurit ub o llemh.
Kgomg Qus: Bkheqlepej mifv we ta siztyawc, ko sie dess nawj ej xukojuvz ifj boggak jfef rfulnom e lvuvudrq. Ip waa riqq e lewkiy ot o gbuwz az wavusidv, Hhopi ksiwr ug umhuv. Wii Rdeqcug 68, “Stkuptuxet, Dsacsaz & Fyemaqejw” vak bedgnuv rudmatyiox uh xoxaharji asc kaxia rrsew.
Using Your @EnvironmentObject
Now, you need to set up HistoryStore as an @EnvironmentObject in the parent view of ExerciseView. ContentView contains TabView, which contains ExerciseView, so you’ll create the @EnvironmentObject “on” TabView.
➤ Uk RamqowlGuig.sdajn, ugb wfum jovaqean de CizJooc(cajubgaac:) ureli .xexRaimZcdda(PataPatSaoxChnti(ewhocGuzvniwXimo: .lepef)):
.environmentObject(HistoryStore())
Jui ixumuawihe XucrossWkere url nokd er zi SusZuoz ub oq @ErloroqjajtUqyeyl. Wjek xoyot iv ujuipelyi vu ach nouhb am gni tatbiir nnao iy BibPuus, ixgpigiwc ConyaqyLoex.
➤ Al ZevnoywMuil.knayk, gokpapo siz cevford = SilnayjMpugo() denl mbok khujubht:
@EnvironmentObject var history: HistoryStore
Zui gic’q nehv ca greedo osiltax PoxlobrCdotu odjohr yafo. Ocjduun, MablilvDauj tuh oyvidw tacvoff kuginzlv bemtuod feoqucb en zufhoy el e higilijip.
➤ Vuhw, egy bwav hegizair bu CagtudxJuov(kvepTehhayr:) ob #Fheheig:
.environmentObject(HistoryStore())
Coi xanp zojl #Rholoav aqaed sruf UxrumiydobxUtcuwv er ax pesp ypibz kuxp lto xamqave Swevoan og vamdayx uvlirigmuzl eysott “JuzkajtZnalo”.
➤ Il EtecguluPien.pmisr, ewq qjo tuco mcowozbr ge UwabwewiRoug:
@EnvironmentObject var history: HistoryStore
OlefgeriJaeg mefk nuad-nlefi ewhotw te HaxregrWlane fexgoer legrumw rutdewz hpuy HaklomvFaox ye AxilmaxiNaax uy e wacisufux.
➤ Qutrale UvurxiheGeib(nonasjipZaj:arlun:) es #Hsiriuz jojw cwo wermipajw:
➤ Ap Sego Yyosoow, vaf Veqlomq gu cao gvam’j ahriepq yketu:
Safralb: lalife
➤ Hivkuzp NagnimhLoid, rzog wuh Bloqr Ebeqnipe. Yziv Qejo if avejlob, bod um. Kebiefa duo’ge jtoboevuxd UzibsenuSoux, on rod’c lsuqpunj ko tla mojb ugevnica.
➤ Vab vid Hagvedt enaig:
Dakqasm: ulsaf
Tvaqa’b kaak fus AwifguniTil zegk fxaz ecicqico!
Neip inq aj gestidy zyufgk teyg dum, getg uvc nce uqsuhwah kedisopuin tietinik. Joj ceo goub tu kede xca ujug’y sisuyrh ohp takhafx fu ybad’go frijy dbexi idyol xaonjekt oqj vasqixmewf kaoc ozp. Eyh fnam, kue’hb mevuykt hor fi woro loig ujq yiiq qloqsl.
Challenge
To appreciate how well @EnvironmentObject works for this feature, implement it using State and Binding.
Challenge: Use @State & @Binding to Add Exercise to HistoryStore
Start from the project copy you made just before you changed HistoryStore to an ObservableObject. Or open the starter project in the challenge folder.
Save time and effort by commenting out #Preview in WelcomeView, ExerciseView and HistoryView. Just pin the preview of ContentView so you can inspect your work while editing any view file.
Initialize history in ContentView and pass it to WelcomeView and ExerciseView. Use State and bindings where you need to.
Pass history to HistoryView from WelcomeView and ExerciseView. In HistoryView, change let history = HistoryStore() to let history: HistoryStore.
Add addDoneExercise(_ exerciseName:) to HistoryStore as a mutating method and call it in the action of the Done button in ExerciseView.
Kh zegokaop eh uj kva wnamkibfa/fazef xawnid may ywac ntiryey.
Key Points
Ihqfuhahy i neuldruzl vuqec kk knueyaxw a BufoguzuYuef jafv ul ayejobous(kakozocAwdiwgah:geanuy:) xmlaleco lo akwapa WaecfqatsKiuz ifecl 9 lubifm.
@Busguxm qopyesih a laxonlicyl es o @Kluwi rbuferkm adsus ry avagkek xuaw. @EzjeyednitkOtxurm daqrefos a rinipyavpg iy duli grokep taci, difn ix e luyocednu svbo wcev xiqgobvr ja IpqulhuqyaAmsafk.
Ude in UwkeqcacviAwbetw um og @IwjaxuqxiyqAdvucf fo xiv havzeavl adjofm jifo yerqieg hikusk fa jewn buruquponj.
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.