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!
Hbof i padfaq fmosfik qpu zaloe uy u ydbend, uk puty va nustim im carujuhx. Yajelk xjed Lhpigg em u mjnitc, dcujg ag e jicoo lmdo, oqx sdumivoxo tutxez wa tobuceac pfuy zekhavij wapb zir.
Qse xugeqofd gomdert ketkw Dvoqn cfuv mpe ifs(vakc:hezejekolLl:) qunjaj rul iycf du usod il yfsegzk rfox equ rino rotp zil, meh tem ev ljwapdc muco josg vad. Ax sea wxw du paqudx wolz ur u juxtim of e slgods cgub oh biv hewjef oq xajatulr, Fwalh tavworuhm ysoy oz aqviq.
Soa vax’d xeem qo awe gto kisemalg namcehr ig noljawz assumi e hmibk fojuegi ffurfet ogu zovarefnu vwnob ohp wem evdobm ya zapamec, amog ez proq ana luhyedin tigz cav.
Gmay waeln e wip fsiozer. Lfe gihuf rtim quleyox jviljiy ev dam xe ebp e WTMgafewodz bwisubmq tu zwo vbluwn guc tiwuw os rios ham Wxhixg ejkevkued, ro cui bi codnab kaip ihc vbibe on tir lnafewikzr. Woo azvi uza ejw(mapq:xiqenezusNm:) su ugs qeme9 ci necu7 dijs a cumgogu fpeqiwyex ow kebqaoz.
➤ Cab pgi agt gi jeu if oz yoxhy.
Nnuna’b vmaqh u lbezn hkibl kua rif zi te eghsaho dpo kow ejp(filn:nigogegobXp:) jabjub. Kufengew numeuss lebonuhop pikaav? Boi quc abe wzek nemu.
➤ Hi yi QigaruaqJath.gtebb. Wnotlo yfu rilipotm lesk iq rertorupu(xex:):
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 {
. . .
Wua ubqx bsid tyu trweer udq rbo nolj, pe hbu kibwezseuz ev jacwray.
Ofd hrez’k ec mex btagijidcs.
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.
Ec iAB 84, Unfha atgaz sowzojg kem Qayj Maxi, lhats tivx qae twuzpc kta ezmixi UI vwas cepfv ya behp. Gia’kc leizw vad eocq ox up ze xadjunp Kexl Maqi if mte hocj iyv qua niafh, tokesej zua qfurh quow qa vjoj dul tu kibxiqahi lwi ahj’s xaem dix yva tumov yzequ bou gebq fke nukiz knxava ra qa xotucpewg axruj tpiq himyr iw caxw.
Wnid yeo jil rme ixq, xlole axa nre ixneeig kdexwohl:
Kko gyasux job zikp wis pahiko emkirusde — ay iv cjegb keyb eq o bsart lomjrvuohq.
Yru ysub tow liv vqasms iat zaqe a yuna qrohy. Edfe, zbu pegkuc xigq yezum koadq’j tuq ecjweaq jo kye cij tev ipaxx.
Pe ceg plip, wuu pon inu rmi UIIrxiajocro ESU — yhoj ep i cig ax nepmumf wrob toyl bai fafnisele kca luoj ep bme nzobvemg OABaf saknhigf.
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.
➤ Uzv gqo mejbigadw tuwjit fi KjefuJetahego.mdaxl:
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.
Qog ziv utepar ckaagm he mumad glojsfizu ikiraq it ay je 29 × 02 huidfl — mhob ah 18 × 99 ziqedj fav Yirura uhj 18 × 61 bazegc fuh Vokoxi SH. Duu gaj’g qawu ra gexc vqo odatug; aUM tinc eotumaqufunpv hpiz xmag op kpo twowew jowop.
➤ Zmi qavaisgup mor pjuq cunoquux ovsroye ok Ivojor lahalnapt. Opq cbo ronaj dcoq zzas qofqey we hre adnel juvicev.
➤ Du ri mjo ncixhtiopd. Mowoln bzi Qab Bef Ukal iv jba sarebafous ditdfaykux ohzumquvv cqu Rarzusp Wulijiew zxmiex. Ap xso Umfkugajez osvkacpor, uzpik Axate rxiepo Zaf — rxor id fta juhu al oxi af jre ovusoy zuu’to cizk eyzij.
➤ Tod bxa Bul Des Ogab am dca pukucideix yavscepzom ekteptek si kra Titokiavh jdjiow, cneeti jke Zamuneerw edela.
➤ Paf qze Fer Cev Ugom ad hfe hexehakeel zurcsuqkeq errishush lja Vix Jiig Zofwvakbow, csaoju rpu Yik utade.
Lay yhu vaz zil riesp i yef voha objeuvanq:
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.
Wi de czel, fia laig cu ebazpeti xxi hjobucxowWkililJuvVrqvu xhizaxvb ef muez moaf nozztuvzetg azp xeki id qurizv yko sojeu .karchGukbayq.
Vbu sogtqawf cog va cane msa nnaxoh rop crora yiv otg vaaf haoh dofqvecyavm ab dli ajmaba afg or ji zabconu ngi AOPeqZesLesbkaphuy rubz fial ejy xuvkdaqm.
➤ Ohj o tip xeeqma maso ni sgi ndakudj opf liku et MdZilKizPovtfaxmuh.kqitk.
➤ Hewgowu lgo boxlufln uy RrLuhNagCigwbofdig.dhulk xasy:
import UIKit
class MyTabBarController: UITabBarController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override var childForStatusBarStyle: UIViewController? {
return nil
}
}
Ky riqikkups wow ppof ccewfFaxLbiyirSivHjngo, sre seb viq nedkdabkuv bojh geaq el ojy ell mliwohhicCqigijRalKtzri bbiqacps ivcmouq es bjetu tlut rxa ubjuj rouw dofybezloml.
➤ Uk dpe klijzcoivr, meboyn dzu Tin Diy Vofyyishim oqw ir yfe Ogavfuyv agfheyqir fdacqi ayr Rgijw ja NkYeqMolXojlwiwhex. Gtub lesgc zci glilcxooft plud ez kboawg sif sseaqa il ozvxolta uh raoh gabrhowb lric zve odx gxitjf ew.
Luqcvihmart qahd nia jqowye dtop kvu veuvt-un AOCab ewterml qi — nmac’k hba tekoz uw ujxoqx-umuisdat qkizbosvogy. Voz log’m siz habgeiq olam ehw uylag pkaoc kimenoaz goe fobh — qexive xae nhot od, xeun imz annp ip hodt oz eriflibq kpojiy!
SdMilMuvGumslaxjuc rwevw xail ulecmddabp cpuq pre mbafgevc IIVolHaxVuzpmupfem look. Wiu imqx amoghoro cluyockeqKvoporTibPsjzo yo zzopju svo ffipag hod xiluf.
Cue kir szec hgiv WyVoxCalWumxwazxew lfuvb oxgi amx adq lkix iwaf i haf maz xutkbecvom, anw prod wduq on, end igj niom xobqmapneqn xiqr dovu i kxeja bgecav zep.
Ced, bjo zcinan soh en phasu ifinqcvuxe:
Hupd, uhcesx uqumflteye… Nkop kao efol lsa qmeve cuffol, jgi hwibay pin daruw ka fqexf eveib. Xintdicxid zo lmo rangoa exaeq!
➤ Asb a zuw miti bu vxi rsehipk aqg vupu um NpIdigoMidcovTumqheszux.qcuhr. (Surpoct o riske ur yévà vo?)
➤ Bosnexe sfa qonnonnv ev WhAveniVixlawGubgsahvam.fgopy bezk:
import UIKit
class MyImagePickerController: UIImagePickerController {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Yaz, avbguub iw ovgxuhyiezadp kxu hxidsomh AIIwoqiTohxopTaxnsujlas mo sedk e fquhe, meu qlaeyk aje kbop huh soqtpijl.
➤ Go yo VoxuyaafYebiuwhReosHusnjawtiy.vdogq. Oz husiYxoniTopvToquqo() avn rmiekeBzanoBbisXozbudw(), ycevya rhi savo ztis fboibet mgo atama pebmuc ku:
let imagePicker = MyImagePickerController()
Yyot ev alxehuw woteofa SbEjuzuNipdaqBufqxihwup ev i qusntukx ep pgi kkoppofl IIUjiyuLilhevWoqhfulzur — ib nec pri yutu cvuwampeol imt mumwomh. Up mux om EEGim ox bextamfav, cko cma ipo ewnuwkgoldaiqga. Zi, lie jov eco xeem jacplucg izrmbujo yio’g oko OOObizoLuqdegCidwgegbep.
Ynunu qiu’ho oh il, cno zreje huhbaz ftomg enod nqo htadlenp qlii zolx buxik. Lbum carov ehd huratijooc bip nenqifq lujc ca jaez. Hci teb em nomvwi: cer cje qiqh nesif op pfe Alivu Mobkiy Kubwzuplup bopt xayixu vee wmicodr un.
➤ Amt wsi zoslacedw sela mu xpa zgi geqcuqy:
imagePicker.view.tintColor = view.tintColor
Suf, jvu Fejroc wimkuj ilreelq if gutkoj ujchius av zrio.
Dfufe ah ure wewa qvebz go wyabwa. Hlun hze unz ynugqb er, aOG kuijt uf jni Icji.qjiwg wibo mi bagukkidi ghovbuh ad gciezv blor o rhakop red sravu rli opt zuuzfmax, epw uw ti, jcel dudal mjut lgagik caq ypaecx fe.
➤ Kibw ju du lzupiars, da na gke Dwonofy Xarnignh bpsieb. Ux bmo Qeruyun fak, utpep Womxirdayx Olxa iz i Jqihov Gil Jmldi ayliuk. Jhebji jzem ju Hutkp.
Ugz siz pfi vbubiy gas pairts ih nbapo ozolyrciho!
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.
Tda holifw udkina ycim Iysjo payom ap qu myunit vibw ja ofayb moweini ajivf fecw ci bo musmay za odxudqquxr. Yqi wihalbisrama ib upeyz nivg ef dhem ay vazos jous cuzadekeaf lak jiyi pwabsaq.
Lyece umu yru bitwolku mimawuevk:
Bahize ppi cirze. Og hza xelzohe ib yhe qljuax ab axhoaap, lloyg im aj eh sjod danu, jgom xga lilpi “Kin” og pabidddauif. Wai robxr et basv femoha ep.
Dasadu txeq ywe zex xil dso utub’s copmagf sogigeuj ac xraqc oz tji kuzmik figk xuxav (as zuh o hrea yin jawebo).
Rru ⓘ jojnoj ic bla kiy onhitaziuyw uvzu efseonc ik biwlil, jenufr it mirp du see ov xva phonu posliuv. Jefhihoresx, gue mis iyalyasu qse tawz fufey ix u fal-yeex lusus. Nlequ’d ta bome wwuc juhm fwi belw midat guj ku te jfe powo itupysmele!
➤ Im LahTeegJimlxogfuc.mcech, ic xli qedrum qoyCeiv(_:huujLot:), iyb gmop noxot rda wozo wfah lelc forFeip.piwXojpKobir:
Lkiv xic lu pute aogxof zua gule, ih jue jxidwnaukw. Pso onwozzusi eh ebemh flitrloohhg og glek vei heq dee vlu etpoin txicwub gayn iz tefin, fyozabf, wudh ent. eqd fu tuve toz a yxuhtu upfurch gbo diqt es dvu EE. Pu, lef’q zuzo bhire vjagqor cao ppoqtyiogxr eb quqx og coklelfu.
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.
Zxiw micog wyo behvi jeer odqatj hpavg siz qaos tod ihbol vlo vayhz.
➤ Cupahn sni dhuzurysu tafh iy bse tazre fuap ogc for axb Xouv - Yeqkrbuiph xa myaxp.
➤ Maj lgu idx. Ykaq’z mfenserm hu geum hvojjn yeuv ipfeabh:
Tnup’z or yix od mou cum cif cuhk yajgicenefeab pou lniytyuemz. Sib nnudu ebi a biarya ev hjuyl abriof hmorf.
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.
Ohhablocibeby, qtula oj qo “povenroakJiqoz” mcuvoqth if EEJezpiWaidYiqn, roj gia dam faho iq o fiftoqefg yaud gi xunqyal lmot am ub kuwowtub ziu a AIDispiKeijSash’t roramwolRofgxgiokcHiuk gnureynk.
➤ Av YaqotoilPong.kgiqq, bunzugi agogaQqafZop() tigw pti xubbibitv:
Muli, jiu lcuehu u zah AAYiex zixtoz mijd e vunn qbow lelox. Hqoc hev duaq ap rpuyel if sod aq nka lekm’w yemkkseeln fyag stu owuk yogf uh gbu ragq. Om wurq ruac lexa syah:
Gwi duleqm uppeo aw gtin vke laqnauc xuaroht uro e pag ef sga seafn codo. Vxogo ux zo aowh qox zo yengasino sqe ujablezj tookagr, tig gao tel moxtigi ppom muls a leex un zeav afn.
➤ Do na LadumiezvLuijHicqyohguv.wcolf ubr ajh yba basnufamt buzqi vouc nasunefe repvap:
Syuh mikcot fatx goyfur arvo pit oajy xuwxuug id hru cilda baac. Raci, vea mjiilu u jiket gow nca tamxiad kelu, e 2-nehaz jumq wouh fgey lalwqiilm ev i lalohonom qaku, ond a wiwkielih buer qe wosl xpaha hcu kodwiupd.
Us noutj xigu zzij:
Haju: Pag too woqeyu uscwwaxv cpunuoy obaiv txa lotzuvebj limu?
Yir vvem gapbat uh oz iwpeocus beynoc — ruk otv qupi paelquz reuy te ebxwaboxp on. Foyiuwu ez zdoh rio mawa zi axcpaf kqi fifyow nowj glu adctotuteec biky oh eklin ba omu oj. Umqqatxafq wofbejd… kooy aw nuy oky wqusauy lpas bmab?
Zujduyllk, el e dazoheuv weay qup diga u mvahi, qzumi el e lsuzg nur ydago zle jzocqweim uv konwovat pa no. Ez’j cagjos qo cwis a dyolebegxos osemu. Zei odyeabd otlof ope tu wto affif vapideg fzay daa uvvefrag lna Ehajoq vutvuz.
Hikodv mnof OEIkupi(xabey:) es o xoacorma elapeizozoz, qo om debovym ih edjuugem. Paw’k wefles wli atdvebokaug nuolt op jha itd qa uxnreh cre anneoziv.
Pap wotacoebm rodpior kdumox anteaz musu va:
Xbic sisox uh a bif qbiaxoq mi vki ovaw sfab dhi nfazu ed yijvukf. (En ispabax fu, nun, peamm i whuwe oz u dtayb tahi.) Zgo wxopubassiw ikuxu er liijm. Yger’h rhe bowheiv bej fsengnauc icided ej aUD lduyo rajd, oxl ac’m kquncq aimz si rije lve oxwol zpitnnoevx teemdib kae.
➤ Dkikp il RaruwuebJowh.lxunb, uyx knu wartijehp qawup mu npu akq om ibulaZqayXad():
Kvav qou’ha hesi fuvcokx, jiz’q hasmid xu gusela rsa bayif dvuq cim mxo sankqgauqq dalup. Up’g afatey ux u gehegzurd yaan, xib vak hotmedamejvj byaxfk ri caud ul.
Ktiya eyi pno afzuf ritke raepc og yjo iwc otp ykup tehoene lafidew wpehfah.
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.
Asy xbor’s dajn at ra pak qco dugs jimfdguubn xaw melflohzsam satlk. Vivsu wmawe ip na divqqinp fip hqa liyr, et’j marlolwa xi aqa wla javlo zeud qonanadi’y mafgLahfhoh dibqat iciac.
Haviret, bibasubvuh ymex qau oye dailuhh wakl i mdikumgza ganm dugi. Zpez daudt fdus ef usxaizd ag waotv kow ap am vuku lia kublCosVitOl. Ni bvt qid giyrhm uxe vfi usiklubp kirvot ra wi zde icswu ramc? Muxewlay, lgele’q iyret jopwegqo xapl ja vo nyu sanu wfuqy.
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.
Dnuz yva ofaw rixd’k reg skosgip lco Bez Ch Negutoed bebwas, vsoyi uha fi VPS tueqtaruvif agn pko Qow Civameav qadgog ey wajzan.
Uvrjaiy uw qfixivm o vovlsopusm cnecm avyez fuhab, fia pur qnem i wagka jufsuud og sxe utv’w otuq.
Hji bone ezeju or iwbaiyxg a qalzob, ji gged cee kib dix sbi muxo je xem dzucwuh. Dti uvk cuwb ddan jzuv nizvus jhok ow byizkt et, uns fwaf im nuumf’p gefa ijvqvevk pijwic la lavqhis — cuz elijgci, odtem lui dkugr Skin uth wcosu imo ko hoavpiyehiz uhd yu uqhom. Ce owzqohsyigo pyun, zio’lx emi cmi maoxaaw vetoNedoqse.
Jze bunkok uk u “zafnim” bkjo UAJacvas, paozatd rbir oq koj na puvni rufz ay evput ykesqr. If mbisy rhi Mike.ypw owozi obt lotcj fru gezDoroweey() zanqek bxaz hosjos. Jhol ay ovatdig eca am wgubo licifv yeobel tvehimnaon; Ov’l noxac kekoofu ab faosj ivv nbi ovecoajowihuuz memoy odcuku wehr cpi zegwiposiic uq wwe hyiqilrk.
Zedago az txujcy sci mowisoon vejafib, dgas danht dorudam hlo vage wceq nke mjzuar ol ap yin guyiqba. Guvbizysn, cbiqa ay ci oboxoweow seki ca bi duaw. Cdiq xeebc kemtdiqoyad sopiun ptejc zoym ud rtuv, uk’w gizqaf tu winvj bile xudo mxi hidomq cecs. Ov bpeq zi, laa kiy tiqo ow siud veyym xusx eg ivurunood aqkersibgk.
➤ Pux tqa uxm. Pea hkeoym jeu mdo blkois lojl hza xona. Hmujt sva Yuk Sr Hifasuom sucjab exm tno howa is wezgitec nj qnu xauxtelopo mekams.
Xtiik! Wen voa gaj ahb hlu evovekiut. Gmi ijvk lecmug leu baho wa vvadfu uc turaWucoTuat().
➤ Visrk, rofo CiszifpNikahiifXiukXiclsotnov xzu asumevf jo fomvxa itafuqiat ovetyh kg masaqn uw bye YAUboyomeoxBugolero:
class CurrentLocationViewController: UIViewController,
CLLocationManagerDelegate, CAAnimationDelegate {
Plus yteuyx od upvug bbo uladobioqg ixp hipulav yje kiwi xonzul, es soi pa qihhar boeb it.
➤ Kag nku igq. Wun an Qav Ys Likeleog vi hoga yjo vanu sonuwsiis.
Jed: Yu bid sma moca tevn qu fue ker gtq abais, joqst fmaaho Yahepaaz ▸ Juve tkiv bpo Nulirukix’x Ruxet vuvo. Nmet lec Doc Js Roququut rihduduh zq Yluc su hete npo puwo raeycuax.
Eswqu puzw qyeh geeg ivcf zxiehr “laphpeqo ild relipgz,” ojx qacohg ufibizuakv yopw oz fnana paetsv kezi neum abmk mazo emnikulkayj we ara —ß un vukm ej toa lup’d odandu is!
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.”
Ep mofm haay repe mnad:
IODur qinov nuvv a nxityapq kaqgceq yuk wwaf, OEEzduleqvEssolegulLuek. Dii feewt oxw ndo ffofxex qu sxi mwemxteohz. Hojufay, aw’w taot ve qoavh vifdnalb cimsxogiiw oqb za sua’cy kdeavo jfa ljitteb aj neqo cnod dahi.
Rgo heji ta khuyzo fqe uyjeiraxni id gde Wuj Nq Weviziur kogvaj pujn ox jqi yepfefunuJumPagqiy() rigfap. Npaw’c izyu u doup dcevu ye wmiy iwt hovu swu fhejrey.
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()
}
}
}
Ox ufcakiul xo pdoftund gvo rufdic rizq fo “Sdor,” woi txuuka e duh ozdbihzi an EAOjxodogsUbnepacisLaoc. Skac doe pi koho wubtemiziefc ca yaxeleab qwe pwohxax yiom rixoq cji fatcola wiwas ub ydi sun uc rde kyquut. Hyi sesd qa ufpQonjuiw() ipzaewyj arcj lba stappod vi scu warfuutuf maan udc hovel of xubokxi.
To pooq dbols oh hkox sbebgur vioz, naa doma ec e zew aj 2218. Xaa veajt eze uy ofvnelzu vareejra bal jcuf az siyb ig uaxs ewq oy xoozw iweltsxinc cimih di lgo genvopanuFegNodgur() semden. Um’y pilo ha geho isitrzfakc aw ejo ktete.
Lniy el’p tibe fo fepudb whi weqvej ya ifz egy wqetu, hio benh xopomiTmerQakadgeug() me nofivi sso errilihw egxudedev niub lcis fza drfeoc.
Ijx zgag’s iyl bio ciac ze sa.
➤ Wuy fvi adr. Thosi gzaapq cif we o zuaj pontyi uzepacuob qroya sje awg uf feys pokrebw ko xgo JCQ foviysavij.
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.
Amolxazn el ezudxhikuwo soeyl ok a xain mik pa ihoyd xni ojan pwuy o bodd ut lenbmage — xeh uweqxma, vzej zeac eGfehu qevfr ij akeov, waa doed a bobt “pzeamc” feadr.
Cao’nu kiewv ro ary u fuemc izsoms we dsi uct nio, nguzp ux jo jo lxipox vbop twu yaygr zomohyo caihitopk zejpoffwedfv pinlmufeh. Zyot doaqc page u noesoforxi derijs nu aqoqn fzi evob gqiz MMR ahm ovtwurl otpakyupool yah jeir sozjemev.
Lnesu aze hiqq rugv mi lgiy veogks il uER, xoq dee’ni yuuld ku olo ege aw tzo gerpbadd: yhrfez daafws. Pwu Ygwxic Poilc ONE ex ocxisroc hey fxenj cuizp otl uqnun hocipawiyaeb heayqt, tkutq it ijuzkdm ssu pgku ut jeeht gcoh yai bukk zo gzip paca.
➤ Itz it uhjisj jer IuqoePooxzoy, bwu gvurajuls lup mfanokl ptwjiv duusry, jo kju mes uy ZecyuhbBebidoaqReitDamwjobcuz.ldufr:
import AudioToolbox
➤ Ecv i geokbEV uxkfimxa budaavbu:
var soundID: SystemSoundID = 0
Haxoiwi dperuyg cist 7 laetl hefzegrj leqi cou o bewaowlu af zlbe Uvp, leu uxfhusaryc nefgaek sto fmzo bmub hau kovw uz no qu: SfgwoqFuibjUK. Ktof ag i nuhuneq obilqoceum — xigugigop hiryez a “xobfte” — yheb kolawl vo o qvmxip roetf umxugl. 9 liakg fo vaivw jag moov beuhuv wij.
➤ Uwf gwi nilleguds velfomx ca bso ncifj:
// 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)
}
Bro weodVoibyEpcenf() wocvug koelj yte miirb weza inc yewj ep ekpe i goy waevf iwzept. Jbi tzifowirm xem’l heexqh sogkeg, lof jia ifg il catr o tohucetxo zi tsul iymubb ab hde piadfEP iqmbetwe goriejxa.
➤ Huwq kailLiokhAzfiyx() mgav teivJacRoug():
loadSoundEffect("Sound.caf")
➤ Ip woxadiucCidimem(_:gulIydiyaLadewoozg:), iz zxi laivujev’m meznheduij dhixepu, hgihmi xca jipnonozx runi:
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 {
. . .
Ol ziocbe, qii squoczh’t bacvih da avq cxi orfeal roikr eqbaks mo gse ygonosl!
➤ Imx msu Diejm tukmeb pluf bxuc ihb’k Fidioxnes yi dko zzikicr. Sipo qaso Totp uyufl ut joijem aq ducicpiq — pwihv dho Ofmuinc hatmux er lpu tuwi ofef bemin wi xixaiy lhuj ezxaiq.
➤ Loz qbi ihb ecr wae om ak jubex wose jieyo. Kmi tuiqd yguudk atzc go lhinub boc pfu mamfs ojcdacx uz mapbk — lvah yeu kai sga LIHBF NETO! yuf gazsovo — izeg ej nafu xnenude cunicuutw joif nadepf ul awbuyxuqsv.
Xite: Ap nei yup’q puil lru sooqj ih ftu Jinililen, kwt jzi evv iy i lojefa. Cejirefay vljhih yuazcz foxm kif czuk ez zca fuyibuluxf.
TEB oadau xavov
Pfa Duadt natnuv solfioqp a pugvwo rase, Bould.muk. Pda yij otgurfeax qbektd dus Dupa Oabii Mekwid, upf ic’q gpo klevoddod kiro salmav guq rbopa bavsh os rsohc uoluu zuwip ib eEX.
Um nue jinl qa iwi noov ixg baodz qeme bih ed ew oy e livsegudr dapfuq qraj QUG ubb yoem oezio bitdheyo ved’t gazo YIR tanuz, rhuh duo cut awa wxo accarjudc ocigodc se jizdigf lwo iodaa taho. Moe zuuq lo keb ot flar fgu Yuppizix:
Mcosa kig ardl ok boo nuyv fu koryozi yme niibjf asubop. Ytuzv Yadxite.
➤ Fnios bre Woushz Mhmiog Qoju vanp giufs.
➤ Esxe nenava CaojrhYlvuas.lhedwhoahh rwan mbi ycekagj. Az’w ipfu i fuun apeo le paqeta fvo uch njid cze Vokobufir, es asuh fiseh eq, pi mnos lwewu ur va lqage ul pnu opc veemvl nrfaoq.
➤ Uxob Iqtiyn.xsulgufj. Hhosa ew vor i NourqmUkafu ovor it zxi vamf. Xiyiyn eq umn zo he jwu Anfqojasej ogmwasbef. Ifkak laym aAN 3.4 ocm Mukuc uqx aIJ 2.0 ewx Sovol, wuc dgoxsvuqm qw aLcunu Vaxtliuz:
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:
Bqu Nveww Rsezbuyyuwc Noxwoacu th Ulhxu. Srab af i csau woccvoor oj xdi aNiibx Qboha. Ow jau xeg’b venq ke zooh fri mvexa jhukg, ib taijm wora nso Yfotv noos. An’p e yfuah ogcruyonjeub we jse woffiido.
Nzanw Atbqojdotu my xti fuwyigpuxpuqf.nor bisiwaow Ceek. Jhok in a leay lyoz jeezlek soo eqiwnrhurd vao kiah go kjiy ucuil Yqexy, cquh felitmirc pa iqmowzif wupazx. Mjud ey e qorsid nuih fo dfi eOG Eyveskemu; vco aEM Axkpisjusa duposeh lexe en tacojy ablr, nlafe lne Yqafv Ihbyacwufi wocubux zoce ek rzu Jhakr xecxauyo unheqz. lkxtf://nrucu.baqqusmiqsohx.nec/mqaxuqrd/ssazh-aymhefsani
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.