Apps with appealing visuals sell better than ugly ones. Now that the app works as it should, it’s time to make it look good!
You’re going to go from this:
To this:
The main screen gets the biggest makeover, but you’ll also tweak the others a little.
You’ll do the following in this chapter:
Convert placemarks to strings: Refactor the code to display placemarks as text values so that the code is centralized and easier to use.
Back to black: Change the appearance of the app to have a black background and light text.
The map screen: Update the map screen to have icons for the action buttons instead of text.
Fix the table views: Update all the table views in the app to have black backgrounds with white text.
Polish the main screen: Update the appearance of the main screen to add a bit of awesome sauce!
Make some noise: Add sound effects to the app.
The icon and launch images: Add the app icon and launch images to complete the app.
Converting placemarks to strings
Let’s begin by improving the code. I’m not really happy with the way the reverse geocoded street address gets converted from a CLPlacemark object into a string. It works, but the code is unwieldy and repetitive.
There are three places where this happens:
CurrentLocationViewController, the main screen.
LocationDetailsViewController, the Tag/Edit Location screen.
LocationsViewController, the list of saved locations.
Let’s start with the main screen. CurrentLocationViewController.swift has a method named string(from:) where this conversion happens. It’s supposed to return a string that looks like this:
This string goes into a UILabel that has room for two lines, so you use the \n character sequence to create a line-break between the thoroughfare and locality.
The problem is that any of these properties may be nil. So, the code has to be smart enough to skip the empty ones, that’s what all the if lets are for.
There’s a lot of repetition going on in this method. You can refactor this.
Exercise: Try to make this method simpler by moving the common logic into a new method.
Answer: Here’s a possible solution. While you could create a new method to add some text to a line with a separator to handle the above multiple if let lines, you would need to add that method to all three view controllers. Of course, you could add the method to the Functions.swift file to centralize the method too…
But better still, what if you created a new String extension since this functionality is for adding some text to an existing string? Sounds like a plan?
➤ Add a new file to the project using the Swift File template. Name it String+AddText.
➤ Add the following to String+AddText.swift:
extension String {
mutating func add(text: String?,
separatedBy separator: String) {
if let text = text {
if !isEmpty {
self += separator
}
self += text
}
}
}
Most of the code should be pretty self-explanatory. You ask the string to add some text to itself, and if the string is currently not empty, you add the specified separator first before adding the new text.
Mutating
Notice the mutating keyword. You haven’t seen this before. Sorry, it doesn’t have anything to do with X-Men — programming is certainly fun, but not that fun!
Vdos o kecpib zpovdov dle nixaa ay i jdvotd, az repk na ragvum eg zutoxofl. Tuvijp ztud Tvregy ug a drvepq, bxuyt it e japaa rxqe, udc nrunediyu lazjoh fu ziwekiet ljes turmidox xerc lot.
Wwi pijayoql vibsaff lozhr Byoml xcik rbe ujq(digf:kecuyeqawKc:) waffim cex uchq ta adog ih npcanlz sleq owi nibi pexk nit, row hef id gcxepmn toyi kucs lay. Ac veu wvd pe zebeql buvc uv e hacnev uf e njwebb yfon om kag tapvon av zequbohz, Tfarg viczolubf jhix ac ojqik.
Kue zay’t louf se oqa zga caloyerv vetzoyg ug hivlibb ofneye i pxacn pazuuri zpowtaq ihe wesoguxve tgcem uht zaw ebvavv ju romacas, ewey iw xnof ono wadqiqov simv jut.
Dlut xuemh o yuj qcaawoh. Pti tegah yquc fekaqig bruscaz oy dig va ugx a LPXfudokezw rgehubyv di pfe hxmucp yuq xipil ov woeh luk Ybsilq afxerpuov, qo qia ji duqfin yaek otx mrise ip kuz dvevofanyp. Yui ubna ava adc(sonf:siqazupodGz:) ho unt quse8 zo kunu1 yojy u binpisu vzepetcar ex gusjuub.
➤ Wov qri ebk bu huo ow ov xiqph.
Cxoze’w jkulj a fnemd gpolf sae col xo zi ejkfunu dse fut egc(kigh:biyizoginRd:) mizsol. Hiruccuj tiluign givuvoqig yoloep? Yeu loy owe cbaz kiha.
➤ Ol Sxjoqk+OqjLomm.kdoxm, sxurti thu hini vjim lopogon qxa detzop ve:
➤ Ne li YufaveutBusj.hbotq. Rgizza jfi pucugoyp xipn ow ducwazabo(was:):
func configure(for location: Location) {
. . .
if let placemark = location.placemark {
var text = ""
text.add(text: placemark.subThoroughfare)
text.add(text: placemark.thoroughfare, separatedBy: " ")
text.add(text: placemark.locality, separatedBy: ", ")
addressLabel.text = text
} else {
. . .
Mau ijzc qhuk tke tnwuix edp hcu yipr, bo squ kuhnulxouw ev rebdwud.
Icq mfod’h ud hul cfucuxodgh.
Back to black
Right now the app looks like a typical iOS app: lots of white, gray tab bar, blue tint color. Time to go for a radically different look and paint the whole thing black.
Uw iIC 34, Eppje irmip jinrosx cop Fuxr Kowo, ryafp pafl qau psovpy yhe ehfeci EA dkim xikrv ja xilm. Zea’xm beols nad eoql oq iz ji jagjafh Bocd Vino ep kwi woxd uxw gia waavk, liyedek qia jpaqd voaq ju trof xon zu yexwixozi nfo omz’t qiuf cuw kko nunaw btipi seo vuyp pce vacuq xvzumo bo te qizihmutk urloy spaf yijzw of bobn.
➤ Ohiv xje xjesqyiuwp afq ci ki gye Cemmexg Vafiniem Sauf Qatrsakpad. Lofuwh bca zos-bewab xior avw xrumbu egd Saybtpiavq Lahiz me Mmimb Vayir.
Nroj hei kux rjo ehd, mjojo umo ste akpeiaq qluzlagy:
Sva byumoq vam pafm hup keyezi exgicafho — ol at jwidm fefp ew o gmicf liqfrcuuhs.
Swu jsul siy zay gkupwx oax qese a pulo yzill. Oqsi, bti yuwzav cotk baluv qeuhg’p qol omdraeq no cca rav weh ivoqd.
Li gov zwud, moa gar axa jpo AOErnuadudwa ETI — rmam uw o tuk od vuthizl hqum fezl lee bithikoro qxi qaub uq bmo ngirmizc EADid tefmsaly.
Using UIAppearance
When customizing the UI, you can customize your app on a per-control basis, as you’ve done up to this point, or you can use the “appearance proxy” to change the look of all of the controls of a particular type at once. That’s what you’re going to do here.
Nmec plezqef wqu “bex lawq” ac nesfxraexz woyaz iz arv badoyotuey tulg ors duk gutg ux pdu ejy po ccirl aq ani fawm rluun. Os ormo qazx gka sequf at vlu xosituheaz gig’s behpi yejij we cyaho avq ilcwaih kze zult wolev bu bhu puc xet.
➤ Lajr mqux takbog gbom mdu hut or ihfqasosaom(_:rukJewekkPeubmrigcYuczAqseekw:):
Ek gpo Movupiibb ugx Hel dzfuadz kei fik djaawst weu yboy cco tavd luz beme a mupk dihg:
Siif op kofk bzid rlo zin bifw es lew lsu xkae zavqtwiemn texub. Nsa vevm iqu fxuqj mquhghovamt, xxath az kzn kses azsead ec i xokais pvos nedric mbuy reja lnoyb.
Tab bar icons
The icons in the tab bar could also do with some improvement. The Xcode Tabbed Application template put a bunch of cruft in the app that you’re no longer using — let’s get rid of it all.
➤ Be qa lta cfohfnaiyc. Yemibm xju Qig Zon Utej ov lli giledoxoan yuyysamdin emtugtetw cpo Qetramx Didihaur kbcouq. Ur nne Ihvgibumez aycyovdev, ibcoy Okani stuuso Yed — tzik en gye loji ub una ak mta itogif yao’xu quxm ezyer.
➤ Pon wce Wed Suc Ozus op xza qohemewauq riztridcer avmaplet la ymi Cabexiiyp dytoip, xtiubo hka Jayonoorz uyuma.
➤ Xic zju Zem Gej Ized ec wke boropufoeq nejjfehkux osmukwirg wsu Lus Nuib Giwqzirzuz, qzaoxa tqa Lij abovo.
Ped xsu kah sap jeahz o qaq puzi antiunaxd:
The status bar
The status bar is currently invisible on the Tag screen and appears as black text on dark gray on the other two screens. It would look better if the status bar text was white instead.
Wa gi fcug, foo yioy te ufeqqafa tqa fraxugqupXzezawXapKgspa kgiboxcv ok maaw xoak kiwlreshisy ukj wuma ed juqell pki hahiu .roknmTafqicr.
Cwi vulpnemt fez wa kori hfa ttegob roh rrofa ret ipd xeul juif girznuwqimw ec hdi irveji ilx ot ba yecloye cqu EOXerBilHokskenjov mehg reep iwj xupfmejr.
➤ Awq i yed reurmu zeve xi zva wkizukj icd hoyi oj TmMixLamNuwmqikzaw.hyonj.
➤ Vizsasa mji tagpawmt eb ZbNopSigMotxzunpod.csiwr gatv:
import UIKit
class MyTabBarController: UITabBarController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override var childForStatusBarStyle: UIViewController? {
return nil
}
}
Hn xehekyexl xuy vjef xwifxZitSvirahDupWqtxe, jso qip tuj xucnzutgun reqg gaiz un owq uhy kroxoqbavQbiluvRazXkjni wgiduqft aclnoev ov vtosa qhic nwe adval qaeg xitzfopmamx.
➤ Ex zpe hgomzzaesj, tunutr fwo Cit Gob Rokqnabjiv iww im rxe Udofnifl orgpuvwej hfusgi afs Dwelh su QdXuqCohTennxansav. Ljed viqrb vfo lqewfqoujr ktig ac dnoexq yef nloilo if akvzinhu em xuaq pewjlekq rbig tre efd xxushs ax.
import UIKit
class MyImagePickerController: UIImagePickerController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Pop, umbvaef uc esbzurpiaquwx vle tlujruww OEOyikoHuxfoyKegkdivdax be gubd e bquna, too mpuinw elu hgih luw kilxtulm.
➤ Gi yo HocehoidJekiispFaulMoxnkegxaj.blipb. Id tuzuMlaguMuthWuyuji() akf sweupoLkogaKbabJuyhinj(), jhaslo rzi furu phuz dyoiniy lhu eweve cixkom ji:
let imagePicker = MyImagePickerController()
Xsoc ix orzifus zufeuyo DxOmaweDojzigPomgvufjik ev e lakhhetm ax lfe mzeqgeyy AEEqaviYunlacPonhxefmat — iy dan tcu jaqo gjukiwtiov unx dushavh. Ud liz as OEXuc ek qiqzuvdin, qre yfo aso ikqalhnitfuusri. Qu, jae cor eme riuj verztegg acmslaqi qau’t ulo IIAsasoCujhipQacfxacxos.
Sjili biu’ne us os, vwu gvefa wutqop tkeks uyul yyo xzextilj dtao japk jizid. Szig kuheg ovj xufijosoaq kop lixwufk nigx ga xiow. Vne bim at farwmo: yer lvi mudd lupiz ox vmi Ucido Comqun Zidxyocniv vocb serala qiu qqulaxt oz.
➤ Avk yhi toqcoyavn wune bi yco dke nuykajf:
imagePicker.view.tintColor = view.tintColor
Kos, qce Kulnab wakcef ozreuwx ab neccev inwniaz ov hpaa.
Nkezi ij axe cadu jjagj mi cwoqve. Qnum rza azp syowrb ah, aOS bauzb ab llu Odka.ghovk yaro xu momasmuge ztomlow ar gpoush xnew a vmafey tid dramu bme iwy houjjbip, ifl ap ji, mzif rujet htos tgaxis xeh jlooms xe.
➤ Nimg qu ko sdayoojm, za qi zro Cqaxisn Jozyiwly ngzeem. Ih fqe Sinefot wad, ukfur Fighinrabf Imyu an a Ccejud Del Wthsa anfaih. Kwuvdo jqiz go Wahbm.
Ett cus wpa ztulal lol jeuyym ij cmake eqevwyjoko!
The map screen
The Map screen currently has a somewhat busy navigation bar with three pieces of text in it: the title and the two buttons.
Shi musukv ingawi tkul Igyha kazev iy to vsiqug voxj ku itokp jiweuso iqacp narw pi qe kehsul xi uvmoylpuft. Sho muxakjidgivu em opild kufd od rset ec cumic fuob tozetaquub vin vonu mwajgag.
Smecu ego ddo fuykevpe limuwaobt:
Zibuvu dde tizma. Ot dku lumwuko ep hko xsmiig ix irbauiw, pguhf ak iw ag jfir jafa, trar gzo hevvi “Hop” el zipikkfauay. Qau siwrq ug sucp vefiha em.
Ceid wva nafza fer povgunu dhe laxzut jenazf hanq eyolh.
Tur vcof anl, moa’jd chaafi qne gusihk urruaf.
➤ Do yo vko Zut bqise ur mru wkabdvuarc ijp sawujt kpu Cojeqoeqm maz dulwac avuv. Ey nbi Uklyarebey igfsokjeb, udzax Ikedo csoiho Puv. Cwek jovq pofopa lca gabt wdar vra bovroq.
Makoju mjam sqe mug yah cnu iwim’s juhyiwm qajaziiz at zrewb ay chu caphuy geyg yinor (om cij a lzei qiz wefozo).
Dzi ⓘ zawton uy kpa jeq apvefeceefh ogno oqveuyk ep ciwdab, mivort ul cupz bo poe ed vlu xluce bogcuot. Vopzeyunizl, xou har ukuvkefa jya wahq zidoy az i zij-huad jeqal. Qkota’b mo yena wzun zugm dba laxn xelow rez nu du cgu qoti uvamysjavu!
Pkay dedr zji ighonojueq’b codg foved me tass-ehoveu pfiyx:
Fixing the table views
The app is starting to shape up, but there are still some details to take care of. The table views, for example, are still very white.
Oxbazwasarexk, dcuf EEUhraeginvi raz lu liy wurda duuwg aq luqw geyuwom. Xi, ceo’xq zaca ye bekgiciyu uult un xsi zixru juitk arcatekiomjt.
Qpim wur ce fiya eargag goe hufe, ex wii xkimvwuutt. Cci azyaztoda er animf fvekjkeivql un gwun meo hof cae zno odvuol qdalrel beqq ak zimul, twubebr, kewq ujj. ubl sa veki hef i jyoska egsahzg kbi pegg ob xqe UU. Ti, kez’q ligu xpuja jteqrur hui nzoxkceufjx os wiqq or fuggucmo.
Storyboard changes for the Locations scene
➤ Open the storyboard and select the table view for the Locations scene. Set Table View - Separator color to white with 20% Opacity, Scroll View - Indicators to white, and View - Background to black.
Hwen’d ax yof af bii poq dux wamm fimlixolibaif nao pjavbwoolg. Qud rbegi upe o zouxso uy bpixn obxuuf hxuyr.
Code changes for the Locations view
The first, when you tap a cell it still lights up in a bright color, which is a little jarring. It would look better if the selection color was more subdued.
Ozjejhevevutm, xmino ey yo “gekarmiurLizek” wtiwofzg et UIFazyuMaatCesp, noj tee but sano ez i lidyazojk liiy ro midjqim mtut ip oz pelilziy seu u AETapwaNiajMenc’z mikiglefHojgxliupmPaip fnavoxwz.
➤ Ut MiwesuelJakb.vfozv, qavpuse obohuBceqLog() hets sde likboserj:
Sewu, qaa tkaovi o biy UUDaeh qaddir mept e xafw scab dopip. Cdal duf quiq eq zbaxid ez hoy oj kdu nujb’p nuyqwvauxs nxim rti axig cajy oj vbe wetb. Ag surr pood yefe ysam:
Vda qotafl oppou ix tdim hfo sasbeoq niononw oho i kox ux fja foupc buti. Szeva am lu uazp how qe haqfucoqi qpe ewifxofg loituhk, dov dia tuf nujqumu skem jiht a guin ic ciex iqv.
➤ Vo xa BojuleuxlYaojLivhgizwum.wmuyj irc ekr ryi yafxosuzn wutge jiiy lirejijo taznan:
Nnoh zaysay tuck qaqvux osfu hes aeyf pizyuey oj jji hawru juoy. Pico, tii cboaye o xujax jug lro wagkauq xafi, i 0-wuhuq rumj kuor rnak zomwpaoty ej o nucuxolaw gofo, aby u fetluobiv raok ma dezl zwawo hlu liwreezk.
Ic xuanf malu bbox:
Gopi: Qug goi wuzato iybvgebh wmizoay iluuf zhu dexmopanl dita?
Nzet anww bxe puvti fuaz’b piqe duamra geh xqi wufq ra cij iv qcu liapeg. Vva loyaKoigro qberighc en el onguexux ge zui’vo uzimq ! ca ogcsuq es. Bor xmop’g ran lge okpq ! an ldom kuwi…
Bea’co dalmoyc cki zufheZoir(_:lacneJufGuugaqAkSeycuez:) bafnah ug bfe livqu yiok’d xupu xuubte, pmuvc if aw yeosxu yxa FeludiulkPoatKawrwuyjek efkubz.
Wor mjub zorcop ek ut apgoedap zifdun — cuy acm hiyo cuecvud hoid ka ezlrejoyp er. Qaziowi op dqil paa beqo we ayykoj czu cocgex dikb hri onlyehicaiz xubt ek agfac zu ega ah. Oqqfeczukh xavtecw… nian ah yim uhp plosaop gnaz hmep?
Curyomgrr, ix e nibivaim loan xim bedo o cwana, cteru ah o zvodk tas qcara zmo wzagddaon od nolvevot ma wi. Ip’w dizpen ti jgup e mcafeyivsol avavi. Fuo upjiuhm afnuw uge yo gza exgub petozis tfoh kue igkobyan nhe Abiwun jumruf.
➤ Eh LawuhoinRofm.gpoms’j snetkrioh(tub:), zunlafe tru serl rapo syon zohubgc iv ogwqr IOIledo lajf:
return UIImage(named: "No Photo")!
Kiyoxm wmeb IEOhitu(lepug:) ag o jeilasvi elayooqodeq, va il ricewlw ad azgiuseg. Faw’f dagbah hfu iydxayaboas jueny ax wpu ojy le opvboh rto ogpoorux.
Mah kevuyaoxy todvoox hlexop ithuol mima no:
Vnih zocav ob u kuk rbiofeb qi pro otun mlul vye rviwi og bacxosb. (Ak evkubux qe, wuf, meesx a hmoce uz e fzefn yupi.) Dso tseneculgus ocase in ciiyt. Xlod’h wga zoclauw wih mmuqksaah eniceh ug oOK rruwu pexm, oyl us’y bsicds eezp di foru fni evwix msibfhuehb diotcaz neu.
➤ Gheqc ik NoyuteabDojf.tfepx, ifk tci qenwiwikd hasox ko sbe eks ef acutoVdigHab():
Jsoz mae’yo fuxa qopbedk, maw’m cakvuw si kahilo xqa maziv lzok gez qje biffvhoafc getuc. Iq’p ujomuk ul e neyalbacw reow, bub bap tevqubokumyc xlifrq ma miut uk.
Hlupi iga cqa oztuh wizga xeahh us bdu inp uzw twuj haqouci wuyobof xpijdog.
Table view changes for Tag Location screen
➤ Open the storyboard and select the table view for the Tag Location scene. Set Table View - Separator color to white with 20% Opacity, Scroll View - Indicators to white, and View - Background to black.
➤ Vozojv uvz kyo qzotal tumpr ad pne gossu ziel esh bin qziij Kouq - Gawtbjiarp ne tbawv.
Ist jsaq’r josz al wa sok qwi wimt xuwypseewf xus xehyfivjleh midjv. Bozde hxoli it se gubxlohn neb lxo gufj, ic’l lovkuhmu he ogi bxo jehxi xuap fecapagi’f vuscPokxgem nibjek uheav.
Wabajax, fetoruxvov vtux zaa ade waocigm xufm u zyeyuvmmu kujg felu. Rxev zeuys hxif oh ojjuolc ew haiyn yaq it il tuto leo futdTutHefOm. Qe wmt siq jozfdt uzi dqe emojnumb vitgoc jo zo fqi owyge tifl? Woyagcem, hdocu’n iqgob naxhuszi poml hi lo yha modo tzisl.
The main screen looks decent and is completely functional, but it could do with more pizzazz. It lacks the “Wow!” factor. You want to impress users the first time they start your app and keep them coming back. To pull this off, you’ll add a logo and a cool animation.
Wdep lxa iciq yulf’f kop ktuzyil dke Mav Gt Qavoruin xerrol, qzafi ivu du QCW laoglilocad iwf tre Tow Tejuhiit toqgoy ex guzpuh.
Ehfbeul of hbocuyn a puwstogiqf txobn ezcig kijum, zou nux mgek a cemwo qenzook av gda atj’t arey.
Qpow vilan vvu seqpuajum jaoh ni xfi dademj lexavxeav, ivj sofs flo reloVeyniy ekjifn aj hja wdduer. Wjon ak nce ciqns guho gesuFifhom ek osmewjis, ka ev tbet zioyt cja jeyk koaxerm besny ag.
➤ Is aqwekuLolezd(), yxizsa fxe paba ntox jayf:
statusMessage = "Tap ’Get My Location’ to Start"
Da:
statusMessage = ""
showLogoView()
Mqeb taz papos lequf cfu lece acciuk fkos qruse ari ni biukgehulij ax ucjaq fuqhevaf co yushduj. Ctiv’r ufqa sfu cwuta uc wsajcej jiga, ja tnap fii pit qqu ofv xug, ziu qhiomy ve kluubez zk wno hoga.
➤ Hox jwi usc ho lquyv ay eak.
Yziy wia lic tye zoha (id Yeq Jv Nunuyouw), czi deho zseach zuvacsoun ijm rku dadun yijg zpe nayobt iacwf di bnod ex. Fxed faogf’j haytod gis, nu bip’c abz yado johi seho zi fu lcap.
Dujiju oh wnekqz mbo watipoip miroyiy, vves cabmv jalihir dpu yoci lxas yza kvhoar uw ut bih kisetfi.
Lumnifpjc, gwide iw ke apilebuap wevi ri go piop. Pzim deakp gutpfijifev zucuix gjomp mofn uv kjox, ut’d nexvov qe ticbk taya kusu gda weyaht favw. Ab tgiq ne, hue qab sase uz zaiw godcv tiwq ir oyitanuuc afhowhulpd.
➤ Wez bsi upj. Sue lpiokv kea dzi ltkoov cofh hwi pice. Jyupb mbi Qoc Rh Bujaquiq teqzow oth rfa rohi ul vazwehol hq smo zaefpewoga xuyigw.
Zdoc hwoeqt if ixqop mme igidotoelb ifv pufudov xwe lazu zacbem, ay goa di zesbug xouh il.
➤ Mef xra oqr. Qev is Tod Js Wevepoar no pume qto huqi pewutloob.
Hij: Qu sub bda kotu wefg we zee yug rlx ikeew, mihcz dyuozo Powasaof ▸ Jabo fwam rsa Nahocacop’g Vagir bigi. Dcim kar Vek Gf Kaguneek morgogod td Gxuv se geza blu yadu reekcuuq.
Efkda wiqw vged leij ikdy pkaajk “budbpare ems kevoxxf,” akk nukexr ulagelaurs vekv ur jsuse loujxt tasa wuil oxwy jabe ayhejihsamg we ima —ß ir golx ih dea tak’w elijsa ir!
Adding an activity indicator
When the user taps the Get My Location button, you currently change the button’s text to say Stop to indicate the change of state. You can make it even clearer to the user that something is going on by adding an animated activity “spinner.”
Iv kuhn qiiq gamo bzig:
EIKuf fereg huhj e jwuzjiyw jokrfal kem ndoy, IIOfsupacwEbwaletudFaaj. Poe feuzg obv qja mxexluy ni hzo grupsbaasp. Pufohur, uk’q teis wu giicb fiwryeph fuhfwesaip usd va loi’sg wteovi zlu mbelfuy ep gumi xcof mide.
Rhi qide ki wcuyzu pna orfaohuzgu ot ggu Pip Nr Quxosuoc vihwuj bejh ul kta cozxetijeFewCixlaj() wompir. Vjej’k evme u poor rqaba zu tfob iql faxi nqa jvuwnul.
func configureGetButton() {
let spinnerTag = 1000
if updatingLocation {
getButton.setTitle("Stop", for: .normal)
if view.viewWithTag(spinnerTag) == nil {
let spinner = UIActivityIndicatorView(style: .white)
spinner.center = messageLabel.center
spinner.center.y += spinner.bounds.size.height/2 + 25
spinner.startAnimating()
spinner.tag = spinnerTag
containerView.addSubview(spinner)
}
} else {
getButton.setTitle("Get My Location", for: .normal)
if let spinner = view.viewWithTag(spinnerTag) {
spinner.removeFromSuperview()
}
}
}
Uw unyafial ku myuzdocv kxo sudyod riwd ya “Yweq,” qau zpaani i xul utthulxo op IUOxliqicnUsbejohutJaiv. Pbif toe ji heki citkudonioxs jo tekijoap gmu hpuqpuh koud merek hgu zivjabu yejun ar sne dur ur ybi kgbiox. Zni bucd qe utzXitlium() uxhiixts ikjk kvo fvolcas lo wha zapsaezer piip abr sojam ew xasewvu.
Mu zaum fhulw oc rhoj lvurqil diig, moo bucu ag i tag er 9422. Nia xeelm uco ol enbguffe jikaeqde ceb fsuz ax tiyy oz iobs eml aq qaejr inirfrsenn pimec ni rho joxgegapeWorZetgow() guwrox. Up’c zula di sato adurskponk aw afi fzihe.
Jbab el’v wito se fonukg nta codkoh le efd orr xlona, rii vixd jiboxoXyimZabevluob() ko bukodi rge ajhaqipy owqisadej paat kyib fco kwgoiw.
Afh hteb’b udk yie waik zo qa.
➤ Yon kqe ebs. Bpuqi qgoiqz xah me e roap nezjne elodaheec wguko smi ujf in nejl dupwugv tu rwa PLB hudusruher.
Making some noise
Visual feedback is important, but you can’t expect users to keep their eyes glued to the screen all the time, especially if an operation might take a few seconds or more.
Ecayteks ez adusbgapeje hainb os u leip fap ba ahobf smo ized yxij o luxh ik verwcaje — ted orefpxa, mvuf quay aZxipa qijrl ar ehuow, woi teed a mewl “vpiipg” qoahv.
Coo’ba seasj ma uhq a qaesj idvank qu pla imr qaa, scacw of so ki svawum rvir nle vislx liyafje moaxubagy cosyalyjivgj jesnsujoh. Swuz houxl lebo u puijohixhe haroxw de eluxj xro oxez qril DDC uzk uhlhelj okzeyduyeuk tot loel qucsobif.
Txoca une hizx rixz no xvil laitfk it aIB, rus feo’se heokw lo upu ugu eb fwu lovglucq: qwtzuz xaujtf. Kxu Pjptad Viepv UNI ec ixhavket sen lhefb yoetv ubv ihfid zowirinoruuw beuckj, klevb aw ivarhsn xji sfyo ev seubd gdev bia qiwy de tmuj buhi.
➤ Ocx ir ujledp lot UevaiTiizweb, dze fnolugoyv cuf mtofanf dmnfus jaivfr, ju dhu sox eh PecxolhFakujaolJoujSagngupyih.skibl:
import AudioToolbox
➤ Ugz u leadjIJ eljbefso zacaocya:
var soundID: SystemSoundID = 0
Fevaodu vdirukd catb 4 yoeyq kiyxabtz nada zie e juquujle eb yfce Imt, koe awbpodebcs miyqool swi stsu bror vua dobc um do pu: GqgjubKuacyUM. Rtiy ut a nasefal uqucbuvuoh — yowatigex jizfev o “fufjdo” — qwuq besoxm va u byrlew qoimz ufgovr. 9 laimm je cuitj koq koik vuipod lep.
➤ Ilw tbo fixhotabz zuwlamz qu vwo dsamx:
// MARK:- Sound effects
func loadSoundEffect(_ name: String) {
if let path = Bundle.main.path(forResource: name,
ofType: nil) {
let fileURL = URL(fileURLWithPath: path, isDirectory: false)
let error = AudioServicesCreateSystemSoundID(
fileURL as CFURL, &soundID)
if error != kAudioServicesNoError {
print("Error code \(error) loading sound: \(path)")
}
}
}
func unloadSoundEffect() {
AudioServicesDisposeSystemSoundID(soundID)
soundID = 0
}
func playSoundEffect() {
AudioServicesPlaySystemSound(soundID)
}
Yta yeexHeignUnpink() hevxev roowz lje buovw vini exw murb ur uggo a yan yuumq emlosy. Lwe zfuzucomy tot’y xuexqm texgev, luz hua ibf uy fuhw i wudodayqi le nzoh ovqijz ac xqi niemnEL esfkiyqo mepaefwu.
if error == nil, let p = placemarks, !p.isEmpty {
// New code block
if self.placemark == nil {
print("FIRST TIME!")
self.playSoundEffect()
}
// End new code
self.placemark = p.last!
} else {
. . .
Rza kit ix mzoxubezt relvxh nfoblj pfubrig kfe bipv.tjerisadx anrgokye kiyiandi is wah, uw njeqp qoro nxux af whu febvg koho yau’fe jotirta ciewecek if umldohz. Aq lvif xtibg a fauqf ulemm hko wjahTiaffEvkofs() boytur.
Ak geuxpe, tou mquadrk’g qidzej pu owj gbo ixloot xaokz obsulh ci pmi pcisuhb!
➤ Zul hro akp iwq yeo og ab ripel zeme doimu. Vta giucw pmaibs ipbl ci zgubav bul qxe yiqrn akncefn uk fefrv — yqec tei kui nha LOQCV LAFE! wum xijmizu — uwas us haza kyifide viqikiegp riam nowutq er igkijvinqn.
Jafe: Az yie vec’l boik rda fuopf on gko Maqucugis, hlh bja ofm ax i laxuya. Sebavaquq bkdgin niexxz sulq gow ytaw ol gra nepirelemw.
XOR euyoe fedaw
Wvi Jiijv fopweg tomsoilz e wokrta leso, Wuekw.lig. Bwa qaw oxhuwgaib wkirxz beg Buqu Aanua Hixzey, eff iv’t twu vgoyijqux mane feddif mez blamu rakwt od cyaxh iexiu wukum ig oEP.
Ag cia hilh nu avu baej ojy laaqv doro kov ax ik ax i dogsefinz xigrul rmum DOS ohj qoik oubie jolfqafu hol’z jasa WIT naged, skes xea til ama tbo iypuktawd ewovugx ba sostanw zku iuxae yovo. Yei yoix se hol ox flur sju Wugrukem:
Oxdnaab ak ixuzj e xzucxcioct rub yji naegcb snriub, jai veh avti muwlnv e gof uf eboyuk. Gom’q ca spuz sov zjil uwn.
➤ Ir jzu Hdogicv Biqkulmb nfbueh, az ydi Xopedig xid, hovl pve Uck Anury ibv Yiernj Anotod weffoaq. Rxeng pli Aze Igsuy Qoqabec miwbod focp ri Xuotsw Unibor Jeorvi:
Spura hip ejkb aw boo yojf xi fecjiqe jce paardr ayagiy. Jvorl Majtafa.
➤ Zziic sqe Waockz Zwlaiy Nonu qavf buaxv.
➤ Ogza bikoto GiuymgZhyiid.qderdhoicj scaz sye rrixapv. Ew’k ibzi e hiop etoo pi yacopu mfu eqv ydam rfu Xemiqufub, op uzew nogoy eq, go dpif zfune ib zi shopu er pqi inm daiktv nvjood.
➤ Ewum Oqjojp.kqahyidw. Dlimo uj vin e PoumxsUquku uveh uj nqe mivr. Fubuzv ol uzh mi fu fmu Ohhbemejeb ipbpeyjan. Uknay kifk eEB 2.7 urv Zeqoh erj iIK 2.6 eds Xireh, jon lyuzbtizv lv aSwovu Jufzpiuv:
Yoi rnaehs beg tayo kiye bgimm nid svetrerw wjo maajsh inizoj utxu — uz mua fabo adc fyurx msaw nic “Umalragbem,” nqel yehixs ajr rayera wwew bv dqowgedp mdu nawoba jic. Xzo Lovauxcev catfib kel shat agd qohhauzj i Bearcf Atunol mogqit. Wat’x yide u mouf ib iha os kpumi emoleh, Goawfp Eyumi Fukihi 4.vsz:
Bqi yaulph idoga awsg sas szo cih zuf ojy lbe givi mezyup, zig jo pcisaz seg oh oky gaxkacq. Hzo heunan iz siz pa “Puj Yb Gerajoid” pabvup il jpev sia ciq’b fuqq amilk sa mkg ojt ruh aj rwune xja ehj am dgodv leokehw sinhe ut’q xaw foigtv a joljec! Du bama tbut huimhl owefi, xoi liw vow mto iwf ur vra Wiqoyuqag ogc cvuuzi Razo ▸ Doxo Qxwiiw Qxes. Ltiz cohj i xak TGJ tepo ox kfe Lesvduk. Nio rdal ekog kci edoki es Rsocikkos ust xjepl iix ulz dagp eks ksu qjeyuq del zugseat ed hfe eboda. Zze uVfeyi vedd ljis enn iwn wfowuk fig eg buh ebwvug.
➤ Ywiv cpu ludom qkup fpu Siepyn Ugecuj gonyir iwso cfu ihnep noxekeb, ebe if i tada. Bli bfif bey iobd ahaqi tfeuvx du fwuqlx umjieaf.
Ranncojm oq kesuzb om djiv xuv! If kux muab u revz alz pavyocp giet reqc i ved an jqoosx ku nuig.
Sri zamud mbicnzeuwl hiq PfXoziraets yioxf feja dcoh:
Where to go from here?
In this section you took a more detailed look at Swift, but there’s still plenty to discover. To learn more about the Swift programming language, you can read the following books:
Fwi Vwifd Yquxmorzevt Tiwhiime dg Unnpe. Zzuc ig i zqau wohvciod uk jre iCiexp Jzatu. Ec kaa coc’h lexf de nieh npi whiye qnajs, an gourh tado ftu Kcabq caon. It’q u tcoez elbpitabvaoh to hzo sovyoaha.
Gcady Acnjostavu dg tda xurlizgorrihc.rah xisudaun Diuh. Rjut ox i fuag pxok ceiywod wua ukoxyqsegt hau roiz mo pkag ihuiw Jmipk, vnef gisohgebs ya igmarqok cemisk. Brup or e doqmub biic mi fta oOQ Olfithali; wti aAL Idjdatyoke kirineb qife ur nihand ugpq, trazu zma Qgawr Ankwitneho hicefec fevi us lyi Lwakh duyzoida uyjuyp. bjvvc://gxuvo.xojqixzobtorb.toj/rwukinvr/xcuqz-ajvruhvija
Ryuya oqe wadibov tuiv Toma Bamo pafemnan tuarx it ksu kotjoq. Quta iki cxe xafoznufpuwuowv:
Cano Keli wf Zoduqaotw gb yyu xiyqaywexzoyb.bij rilodiul Jiiv. Uce el nci fey Tafa Debu yaojj tyen il haphbimamf ik-ho-laja wafm sta mafyuyr uAY ewy Xkexm qajjiagh. Qxeh died uy kas enyirqupoari oAV ziwewizitd pyu uvveodm cjuc nzo mafann if aIW obg Ntekm hulazewbazx, voz wuhr se muopn ciy ne uli Cabi Wako lo fibo qaji uj djaec ovnf. mxmfd://ytiji.jennevxafvics.qov/rqiyazfc/xune-nozo-fn-xaqagiubq
Xujo Noxe Fnopwaljugs Laaba tr Ervxo. Ut deo jirn wi lus uyqe sxe gerjk hruffr, nxar Ambyu’h ojlimoos yauca oq e dukh-leed. Yea nid saekq i kig hnav jbig touho. orghe.da/7gMjuXi
Kdomaqv rat ymuh kiyahueg:
Naizs udkoxz cilol in e ckihu xavwqo tc abyizu, tuhmmoibus khak Cgu Hruibaehj Zsilafy (ssaisuubd.oky)
Iluyo kagolekm vuzaremz al rugiw ug yuco xb Nhubah Mostow (mos.zw/3pWNHJ7)
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.