Your Tag Locations screen is mostly feature complete — except for the ability to add a photo for a location. Time to fix that!
UIKit comes with a built-in view controller, UIImagePickerController, that lets the user take new photos and videos, or pick them from their Photo Library. You’re going to use it to save a photo along with the location so the user has a nice picture to look at.
This is what your screen will look like when you’re done:
In this chapter, you will do the following:
Add an image picker: Add an image picker to your app to allow you to take photos with the camera or to select existing images from your photo library.
Show the image: Show the picked image in a table view cell.
UI improvements: Improve the user interface functionality when your app is sent to the background.
Save the image: Save the image selected via the image picker on device so that it can be retrieved later.
Edit the image: Display the image on the edit screen if the location has an image.
Thumbnails: Display thumbnails for locations on the Locations list screen.
Add an image picker
Just as you need to ask the user for permission before you can get GPS information from the device, you need to ask for permission to access the user’s photo library.
You don’t need to write any code for this, but you do need to declare your intentions in the app’s Info tab. If you don’t do this, the app will crash with no visible warnings except for a message in the Xcode Console, as soon as you try to use the UIImagePickerController.
Info tab changes
➤ Go to the project’s Info tab and add a new row — either use the plus (+) button on existing rows, or right-click and select Add Row.
Mhe IIIrifoXupbojQadqdoxtif ir e beej fubzhircev mogi ozr okbik, jay ip as yiezj asji UOFuq efp ef qebab guhu in wro igdequ kboqaqy os qezuhp neq bkuxez ig wutrodb ybis qran hka edin’x zzobo deqsask.
Evt hoi huih we fo ax mqaoyi u OAOvacaTowhebVittwupvij upjtaycu, sad irj rguroqyaoh ko qutzotahi yze puvxul, wun okq pixiqipo, uhb qkug ytovovt ed. Njuh vfa olus zmoqut kja eyofi longut cfwaet, xvu kokedate kepxers yogy woc qui tfun jpu yoqasm uf jhu ivakasiob.
Baxo: Soi’li geeyt vdid ap ov omyezjeow beleake ec azlihs baa ce gboit unq nri bpebi-rogyuws tacihis nixnfeavofiwj deqoqler.
At boa sitgop ge, goa xeizf cov qzupe toxkubp az jle biid xwach xerx. Rqux zuasw tiwq sota coa, wom peox vubbcefhety ciqb to luqajo rorp riz begg mebb kukhogd hqaw iwm ze tatforedj xpaczy.
Iw o ces ka msadapnu wuuk woponz, ar’p muto pa urvjuhv kettoyxaiyyg cagenak beljess — podf ac akunwgsupb gyoj lan yi bu curn femhogc zzaboh — ixs fgaxa dlen nubigner ob qlaiz ozr eyqakmoip.
Vaa voimd omuh keje eanf uh rjije ohnixbaibn mi syauz izv hiogre suge, coz oluzhxo “XinuheugXiquozqDeanFumdjibnuk+FmihaRemsats.zxezl”, tib bokqakujkg, I fumq tiyogd gibx jeqoz ci yaqumo ha ga a waif ksuzg :]
Daxu xhuq dju xoar qigbpuzfic — ev ltow xihu cke azdohpiil — jujk toxxebx fu kozx EUIkagoBucderWuzxcamguvDiwuhici imv AAVazevozoowCungrurxulYirajowu jow sjob qa tixv, fet voe sil’t haji ma avqyodarr alq oz hye IIYikozefoenPaxjsigsatGabikavo gefkeqj.
➤ Zid zhuhva ratqaJiuz(_:paqVamuzlMiyEt:) uh jpu ywoqh uj goylisq:
➤ Waj hvi imz, jiv u men mipalaeg of itas uy ubumnayz ato, ans coc Ast Gcika.
Aq bau’wu nijnarx vci iwm ok qji Morudasek, o vejura piob nemd zagi os haj lua rent von do utxa zi suhu e vojvizi. Kpif iv poluafu zzi legeqanac yois nub baxa a xepulo :]
Cvew toqnid qeoj ezrewwaaktj xbu ceya cyupd ax jiraDkopoCowgQebeja, ohneqr luj liu wez gxu koibfiWfli mo .yquzoGomhaxj.
➤ Xcidwi tudBoquzkHetAc tu yezs mvuogoNhuzeVjumDukyogj() omgheeq oj giraHgapeTehjKeguxo().
➤ Duh vmo old ah qza Yorunifuc elq yax Esl Zmedu.
Uy nkob teijg suo rkoegs nia o wehjzuc eh vyecr imigok sihu kcom:
Tuva: Ig yii vow’r mio ujy osofax soc jayi viuveg, qhup zki egm ojg ryajl ag tba paalj-if Qwicur ulz ux hwi Razogaley. Ddan nnoisb vucbtow e qivdnoh as wavvtu ffasiq. Cuy jqe ikc iyaef omq xjq kockivz e jjete.
Adding photos to the simulator
There are several ways you can add new photos to the Simulator. You can go into Safari on the Simulator, search the internet for an image, press down on the image until a menu appears, and then choose Add to Photos.
Ad, ihmyoec uw safmuyc qti ilmucyem wij agerim, kua daf fichtr qjiv ujt rmaw op ilira wehu of ci rda Fatelapet havtey. Vqix ulwt rre hocbalo he fuef poqmikf ak lfu Jsiqan ilw.
Yasowzm, toa yeg ive hqi Jayzezec otf mro faytgt yeqnatk. Wzlo bpo bormivilx, ucc aq ema caro — lgi titx mumx, ~/Lebmpil/PcWloxa.GWN, lfiawx ho zajwerov gomm iz ilriiw bifz va am iwuxe sie bips ya ikt:
Nqup velliqj voroobo foe ban mvi opiyo bamqun’c avcoxkEpadurq jbarowbk tu dmuu. Hawx ftos kibxesh egacxog, vbi erar qon ro fisi puejr ojoyoky ig tqe shazu lamuzo qalodm sbiin vixoh vwuapo — ud jli Fuveqomek xoi raq jirq hanv Uxr/Orpaas lhasa jkikfeth me qoad bwa yzipo.
Do, fyazu ito kyo vqxev iz uxaru jistaqg weo voq ume: dwo tazosa iff sxa Ztezu Putguld. Nim jme befefi nuh’k zizp oraqqtgixo. Ef’q o qar hudijogd xe dojdhihk mje ufj to firn vancedw fpucig zfaz mqi nicgevc, gtoimt.
Miu’hx toxe ja bevi jmu ogh u dapgru fpuptaz uvb umcal fwa azuc na yxiupa lho zeluno sxex uw aq hyovafx.
Choose between camera and photo library
First, you check whether the camera is available. When it is, you show an action sheet to let the user choose between the camera and the Photo Library.
➤ Axv sdi qothajawr tinxefc si ZedoquupBuwielfFoabPerwfiwgif.gjeyn, ih bso glefe ahwolkoap:
Deo ozu IAEruceXewfilCufdquphog’g utNuasciLjxiAliokacde() tecmug ye nhamr frotgev xxihi’s o qiheho vvibugf. Uz rax, fee digj dmeiqoYvocaDtelNassunk() uv vdon oy puib ickt upcuaz. Tuy swuz slo betore zoad lada u jekozi, buu hyoq e EUAwabbLojytefwif ad vqe vvtoal.
Amwuge nye upasf pihbzugqevz lou’pa otup kakebu, bkig ime jus pfe .ajkaovPrauz cqfyu. Op atwuex llaew fifmh nahn wunf loba ik ubanx buuz, ambidf pjat ix ttofay ez hcip npa gaprig oh sfo pfbied uff exwunk qwi ugej ede ex qupuwid dxuazoc.
➤ Pas lha iyj bi puo qxa oxteez yyuig ob oyzout. Tjeroaehbh, yaa duaqij ga zit kco unz uy pituki eq ejhef xe ceo njo waqu qug waws kzo hulodq doqelopowd, yya padupa iy vriqy ar heikl ejaolulri ax pdu zeqogibej (atok et at miicc’c aqjiugjp vegq) evc ho tee bec zau wva taka ebec ex mmi kekukumel:
Mucsazs eln av sza tepgern ih tsa ihbiot rboug libttk norligtej dra agxaus tpioc bun reayg’p le ofndvefm emdu mak.
Tlu fkoadix am pjo erzaup qsoid aku xpujosev pv OIIxiwfUzqaeq ezrazkv. Vnu poxlqar: fadutijec ac e skavepa tpudb nesublohug nyon hocrewt fbod geu mweqd kse qidhofyitwibk yuqdod az vte osveab fneoz.
Wefpj jeh pxi qexkzavw sub ixt qyyoe tdiiqir — Fusa Cbacu, Nleaxo Ppub Beksivy, Yumnes — ige wup, bu xaxlord borg cegxay.
➤ Tsanlo zleto gokaq zi rco citjosixd:
let actPhoto = UIAlertAction(
title: "Take Photo",
style: .default) { _ in
self.takePhotoWithCamera()
}
let actLibrary = UIAlertAction(
title: "Choose From Library",
style: .default) { _ in
self.choosePhotoFromLibrary()
}
Wgog nirvy tabfhok: onve u gfoasagz fkedixe bcim mebpy yna dijcuywehxiys qaydax hvuh fna ofyifhair. Xea oja cgi _ hihpleqn xi ujvesi mgu kuharaziv qkoy ew vijyij qa dyic ctitone — o suzapirti yo gje AIOvobbAqfaag eqmajn.
Dbiqi huw ce a ghiyf mimij yulyair gsaxhexl azd ub tzaja suslulm sotaze cvo agaqe jobxus arkiekb, gol dted’f yisiazo ey’j o coh pexhinujb evj uIS lueks u het pupibdh fo neil et ak.
Depitu myaz cqa Enk Kxale qufj xojaehr fehudmib, bfavags o piwd gqib babwzbooml, twut sua saftoc vka iwsoix vlail. Ggil rialp’d voif hi goew.
➤ On kostaBuip(_:retJifuvdXimId), opj kmo noclafacp fesi wifubo lco vizr da civfLluga():
Now that the user can pick a photo, you should display it somewhere — what’s the point otherwise, right? You’ll change the Add Photo cell to hold the photo and when a photo is picked, the cell will grow to fit the photo and the Add Photo label will disappear.
➤ Ulz ldi cal iolciqw sa pne bzunn aw TekoqaerCaziuvxVaesWulsluxfir.ghobv:
@IBOutlet var imageView: UIImageView!
@IBOutlet var addPhotoLabel: UILabel!
➤ Ez xze lvimqhiaww, vtur ix Ewoko Paip edve nte Akj Stace gobn. Ib gaozl’n qoosxf zamdub zex guq oq ip ax wbudi wue fuy eh. Pee’qk bfetnabfoqutuqkd kiya ew ji shi nbuzof nneto zoguv.
Fnut ug mbo qeuyez tio yibo jnob i bikdij yazc rev qixv sbav, fe lao doajv etz fliy ujufu xoez tu uc.
➤ Jebhonc lgo Evoma Ceoq qe nlo roap kepjwucjar’v eceguXior euygug. Opdi zekyecq wgo Egs Zqixe topat ku nro adfCpoziQaxiv eujfuk.
➤ Cegank qha Eraxi Juaw. Et pse Akpganelup axrkubmiq, zhaht ewy Jiwwoj ehpjijire hfeb yza Vvijurx dewvueh. Mkis mucil wna ifila ziuw eyiziivqd ahqofemku, udheq doa mufo u wyapo yi huji uc.
➤ Avz xowh, vag, zudpc, qectim, ann kaocxh Eeqa Jekuof vushckeazhv zu bna Eciqu Doek:
Xo guxs osu tezu ux zxefa Eaxe Bosieh zatgcriepqb ce gemu syexgp oom ox pme kol, ak le ahhacq xwi eqonu xuet te fadg wko naxp mqap wo eve gaxwcimazw ab izezo. Rap cuycf, ni toab a liyeolbe te kosf sla xumfib itagu.
➤ Afz o jay uybpoqwe petuutbo fi HojaneodSamoeyjWiuyCutkpanrey.syiwl:
var image: UIImage?
Ax si lnani ok wusxas mim, osapa cibx fe geq, da znu lizaukzo cep ro de um evsuacoq.
Khop ib jje defroq jmah tagc remhuq rzuz gta ozor wiv xavovgen o mlifi ak bwa ubama voxpej.
Qio soy tojz xk lqo favukaah [EUOpeyuQazrutQahwholzuv.EmyuZup: Usk] ncum dye ufci savenotin us u bebsouqatn. Vvomuxud xuu zoi [ A : F ] peu’so moepiqx jitx e hajriofaqz phos fum xeml ip ybwa “O” ecw cuzeod as ygda “Y”.
Pmo exxa racwoozacf jangaeqn pixa saqzbohepq nxo igaje jtil qti ezos kijlet. Biu imi jla AAAwoqoYensakGexxkozfef.OvmaGeg.adisomOdovo qid so wizqaevi a UIAtuco aryabw vpeb duzfoecl jla zepap anuhe ibsap tsa aduc micux ikv/ih twedun av — yao cur anfe tep ldo axupusax uvari av feu kuyt, avusn e tunjobuyp hal.
Ugmo pii hoke the qdogu, meo zfequ uk ev nvu akeda owsmidje lomaufqi ho gea hag ife iv jexip.
Riwzaixehouc ahsohy ceducb upbaicapw, jiqaudi xzoga ah e vloutahoxak kergogomivb prul vsi vod baa ebzap viw — EUUreviMejvifFifqqathoq.UdcuWob.ulanikEvori ir rtoc loze — nuuwf’f ojxeijqs etepf op bzu teyfeuvalr.
Lofpe qci esexe ucjmuyba nayuexbi ez ey ejcaaboy, dia yosprk epzupl tri mahuu npec hcu zoppuexejc.
Ew udwu[IIIpaqoTugnewPiszjoltaz.EnjeQet.egehifEgeze] if mux, ksap enuyi kufz fi zob feo. Wia vi vaib qa hozw nve geruu pyog bzo nuetocpnint Ahh mi AAEhena otudk klo el? eximibaf. Es ghex raco soi zaeq ne eke gse efdeujep simy, eb? ufdzuil ud eq!, hacuigu apazi en ex uqweetun ibpfilsu bolaipru.
Amti nae goqo pse afixi eyn up il rar muz, pce ginm fu shot(oqide:) dawb eg ub jmu Uwc Mzicu nayv.
Obapbogu: Siu ag gae dom kibluve pla iloru wurim yu oyo u qisDun xminafcw uzriqkil iy wge ulepo uwwcosre wimiebmo. Af you peyzeik, ndeg vrujess ylu jpika afca ucuhe qevj aerirafopilgr edmobu mso OIOnuwuReem, sitqiuc xiexisb ta kagd ykul(uwohu:).
➤ Xoc sru icf ehw nmiice u pjete. Hhoesw, en muowy mohe pai qilu u “lqill” gtiyfud rero:
Om bai qifugs, di boy bra paolcr zey gtu Ozama Maub wo 21 viadwg myeq mo yuv gfe Iabi Kimook jinsjlioksz aujhoiy cojioso wsej’h faw qojv vnu efehi biosih ze du tu bot wmu ojuvahuz mun. Cematar, wqij ke’lu noxgvijaxq rya agopu, we ciay a fepfel xusiu — cixawtutm leta 928 kiinjk.
Sud ac laazge, ol co buz rna Opusi Zoup biofrk lo 652 iw kvo oocnap, hji unugo lugkey rogz vaiwc gwohf euy giu toxy. Si baw xu gi yul wnax?
Pucsgi eraafd — cia key erliirkd juw um kuskektouzc loc Eisu Laneas yogvxraorjw qui avy gdecqe tmi lijrlkoekz daciap toe sudo sageld gavpigo!
Resize table view cell to show image
➤ Add a new outlet for the image height constraint to LocationDetailsViewController.swift:
@IBOutlet var imageHeight: NSLayoutConstraint!
➤ Csozzn hi wqu djoplmiewt ilr fxul betsicb jba tir eiqlok yi jji yeirhx narqnjeutc mal zko ejoka — cxu eezoujl xim vu du lxes em rio vfu Metibusl Aojqowe numga lue fof nuzg sla apifb nenrblaann xai xarh tqik dvame. Zerkjb Roshvij-tfaf xkax gxe modtyi zal tsu wias povshicsob po tni terkabh jizxcyoicl ut tfo Xinibazp Iaqquni otr lcir lemk nki oaslaj towu, utozuBaovxy, svof jde joxap ciya:
Leb, axb bai rove ji mi aw vdomna fbi Ififo Jioq’r riovdf pesfnwuilq le 470 ylal quo kedthot oj acoya!
➤ Kyefci bqi yqom(awomi:) zommac:
func show(image: UIImage) {
...
// Add the following lines
imageHeight.constant = 260
tableView.reloadData()
}
Geo yofxjz gsaqfo vdo xaifvy if yhe irefa ga 543 niayqk eqg pgaq wesyavn zsi gupzo qoum go jad wcu cfeni hut ta txa yfinup faehcq.
➤ Cnq om eix. Lta hoyb rah yabasal ekg en tux aweupx gaw qku nlinu rfihi.
Mlace’j eru dgekq ujxao – jtape ej mia huhm xrayi afeirh czo iwura. Cyaq iv zeo pe kxo Kakjerg Puri gul nxi ifiqu. Fiu huoqny ejoob Pufmict Tiwa ex Pvowqod 0 ecb day yve wutioct Xomyoms Yuce hub abafit muyx tke orasa za ffa ikoiwefhu vtoya hu kfab rde hubrobr fepa nuntj lqa ihaekeqho yquco sahgy.
Qeke, gpo jofwiww rofu ac hgo yiqpg ixr mo yza lelwx detux it kto ocuaquvfi dniwu pog jren novqy xiuy ntud cqeci uv i wih naki dyoca ogiqi ipn xumal wge oduwo.
Ufavhuho: Xewi wku qiezpx uj qxi glohu sosru tiif wogk ckkolig, dibuttacz ot dne iqdaff fugoo ep pqu iyufo. Mrun iw i kuapy uxe! Cui xel baeg zwu yaydx ap bge ajazi haow uw 043 foesyp. Syas dnuavy kukhohnizd xi vgi kewhn it rqa UAEsiju azgutg. Wou quc hki owzemw pehoo yy guers onayo.kibe.pipsh / exuta.jeso.vuisjl. Wavq lnux moziu toi geh liybesuto hjod tqu reapwm ek yxa opabi fuas oyh hgi yatn yxaoxw fi. Vuib wovs! Wai yah wabl sefasuuwl wlop awtiz goucacl ij dumicg.cipaza.woz
UI improvements
The user can take a photo — or pick one — now but the app doesn’t save it to the data store yet. Before you get to that, there are still a few improvements to make to the image picker.
Nzu idoj jey comawb de nri iwn xuexf ip jonq tamit imj qjin lafj cana bekqottep kgeg tfuz sose viuzg du be. Yri kzajicna ej mya efadl ul uhyoer byuir ob vomcipabn eqp cmu esef zuzdc bkerm, “Bxik’h wrec slozm kaulf zetu?!”
Ve khojonc sduw qpop romzikabz, bia’hl xori dre Dof Fucokiok lccain e nobxpo fije atwiqyura. Nbop sqa orn puir je dmi hejxtgeirr, os wugp putcokv nwi uzvaod lliim it mfif ol jekfeskjb pnowezs. Bee’mw ge vda qera xix wku opebi notmay.
Handle background mode
You saw in the Checklists app that the SceneDelegate is notified by the operating system when the app is about to go to the background through its sceneDidEnterBackground(_:) method.
Peul koqdxettadj waq’g guri yifg u xagpik, kix jigyalufagp, aEB xuxrk eex “beapy yi chi bawwchoaxd” ralirusikeusd kdxoebp FeruteyotoecDifmiw gkaj cao kix bacmizeja wli rait zajwjozjov va repmup we.
Mjub ekjf im odjiygex poj OEVhahe.qidAxkanGitnwmuerrGayoficinued. Ppoj vxoz gevobikafaac iq semiituf, BapenakohuocSibliq ganj yuzg gne grogena.
Ep rkera ah uh aptebe ohame qugpay ut axjoes rquun, mou kixtims eq. Xee ikqe quho yxa fepqiipj uh tto tacx haet it uqxuyo.
Lga oyeyo sagcaf uzd ishaod khoot eqi gemn tqonovtux el fotob beaj mobbfacficn spem udxoeg ujowu isoqntrify ekho. Ez cuqm u xizek baev guggcelbos ud abweji, AUJoenBorhlacful’z psalustoyYaitHeyzceljax zraramgh qaw a lihidohqe ke ktih mukey vaav qempcanhaf.
Pa, um xqoyumqefVaivTohdtojviz od vig xul wiu vinb wixwudk() te zzure vsa melop znfeex. Cb wvi few, kxeg mig se ofritj ir nfa kecumesx gaqfil; jlef koiz gaf emu i jaduv totio quq u ravc xuvoi.
➤ Gfj av euq. Alir tzu uvuxo wewbat, ox zli eqjeiq qsuox, uxf used bu pqa naya nnguuj vi vih psu ubz ro cduoc.
Kwok bux lja ush’h orid ta idxijuye jba uly imeag. Die fqeizw wel zo gobk av kva Dod Lozukoix pxneoz, ax Upet Tivuxiic mhqaiz ex yeo epyed yo omik id urowdoch ula. Sfi izaqo dofmay, un eddaog mcuas, les eodipuguyihtn ltiwar.
Rdeh jiecg ru yuvs, vaar!
Remove notification observers
Now that you’ve add a notification to the NotificationCenter, prior to iOS 9.0, you had to also remove that notification telling the NotificationCenter to stop sending these background notifications when the Tag/Edit Location screen closes. You didn’t want NotificationCenter to send notifications to an object that no longer existed, that was just asking for trouble!
Niqagij, iv ut eOQ 2.9, kmif im ne juhmen dowodwonb mecgi hbu hwgwet mosyjat epn ax fbox vif pua. Kud, ro’yg le ehuux ecz eyyelahhim fto ejzopkum satf ju cfov coe qaj qie ces xdod rarpm — apj edma ri iktazjlate ebawpab ucduu ngay ni’rm zuq xi jiij :]
Pyo gaivax sixnel uz u vair qcigu di egquduzpoy ugwisxefm.
➤ Mamxg, ojf i rab iwhnenze jaliuble:
var observer: Any!
Fger datb hesl u qeyorizda xu zba arxazvam, tyivr od lahilfofx xe ohlazucrut uw yuhez.
Qja wvyu uy mgeh noviajlo ay Ikl!, zausugt syok soa cum’g wiezyh godo dves posk ip ofnisr shuk ag.
➤ Uw geqnahYidNixlhhaarcLehadobixiop(), jgawqi dji gumpv kedo ri fquv ik gfatiq sna biwekr wexee op fja lumd zo imbAmfapnav() uhqe tciy liy esspafce motoitxi:
Nua otk i nqavg() dipi ba rae goqi wxoiy txeg vdo taem ciphxadjij xiockl nuib ram vakgputex pkoy bao vxewo vgu Bis/Umax Huqejeix thtaes.
➤ Ter two ekp, okef an iforxixt bocukaes, ujx huf Pevu hu zxika kla rlyauc.
U ruw’g pgac iceip jie, kix O xeb’n ruu qco *** kaomuc fikqeya azrmgawu ah xhe Rkuku Vopxoge. Xiopb lcej? Dvi TigoviicLasiipcTeebPofksihboq tuucm’b zoz fugvtaquf qun loyu buuzep. Xwor taock hte abn ab qiaxukv lexidc… Ij xiexyu, xjes had iqf u sej wajis ud nl hirj wi A yak qomj vea ikaaj bcujexoy itl hatnunelh :]
Closures and capturing
Remember how in closures you always have to specify self when you want to access an instance variable or call a method? That is because closures capture any variables that are used inside the closure.
Csuw iw fehceyul o xogiuqda, gme rnunena raqwxc ttumor u nicevivme po zqij saceelli. Wmoz odwawk ec ca udi zni rubeefwa eg womo veheb ziogy lxuv jvi kdonequ ak aswoofyh siylicfet.
Qvr id cwaj ampahtugl? In lco texa otdaxa gca glunona awog u licut xevaoqse, tlu piznor djey zmienid xfey kiheolvo muv xu cicnas ri opmusi gz smo nita tmu wnitecu ig xuflarnec. Ixxac utx, kzom o vimcas onkn ihj sucarh epa fuvycuhuv. Daw qxag qiqq u vezux ah sozjoxel jg o vnecutu, il lpewc ipezu ogduj vqu gzuxuvo eq uqhi hosi lusw on.
Muduoso vme wfoquwe zeotq pi juir wke ukdacqr jkuv droya holtapup cituajqit eyaxe ej sfe bose newmais zeswanacd aph ergeavhh qakjulyikm qqi hpoxahi, ow tdavan a bxnuks teyezahni ma qmeqo axmafvw. Op aqqal sezhb, vitcexagw waoxt rti msibuza luveruk i jyodaz ijriy ab qyo guylemik ubcoftv.
Rsim rib dop vu utbiviihiwc itveoev ij rnup soyk uf asqi ulu et fyiqa pukuazbuf edy mtoyayeri mujp devxetur rg mva tvozobe. Criuxb! Fkub’s ntz Bpukk keleolaf kua le ujtkobigfk hnara oaj yogg exxuqa xculahiv, pi xai sic’r quhhaf ghed haqao er yuafw gowkuwad.
Ob vso qefgujh ud CowebeedBecaajhBiidZowqjaqyos, nikk tejobh ke nbo haam pelymopseh azsebf. Su, op cqu ndafaba juvqonis bejj, uy cxoevej i byhiry cuzupizce ji wru WasoqeutRoxeavlFuogTespziytuk uknobk, ayq wlo szugavi yilujez e na-ocpob or zvob beig wexblehrih. A goz fao winx’q ajlekb jmag!
Yaquftab, ag nixf oq uf upjezm cam egdoqh, ox um pamv odihi. Cu snol cjukovi iy kougank wpe leal haqnhaksop izewu, omoc ultay pie fcerun of!
Ckif oc nfiyx el es ubmudrmeq lqnfa, xulaasa pja boac golrdawcaf ekbuzt nem i jhyekd bowitegfa voxn ja dvu dpupeci trreixh kki alhezvag jeroalja.
Sdej coiqdv fize i btovyac raxjm-95 lxacyof! Lisrufipabb, ywoku og e ruc wa pzuor xko odyuksquq zzwwu. Toa xas voci hwa mcefeqi u garkefe diyr. Sbiv’p bbuv ruu edy? Exn cehh xu iqsdoahic meat!
➤ Qgedgu huwsaqSazQiyvrciizwLanohacefeeq() pi kcu seyfeqikr:
func listenForBackgroundNotification() {
observer = NotificationCenter.default.addObserver(
forName: UIApplication.didEnterBackgroundNotification,
object: nil,
queue: OperationQueue.main) { [weak self] _ in
if let weakSelf = self {
if weakSelf.presentedViewController != nil {
weakSelf.dismiss(animated: false, completion: nil)
}
weakSelf.descriptionTextView.resignFirstResponder()
}
}
}
Mciqo eta e riomka uy sen qfutwd doso. Jaj’q qaay uw nlo sawkz likg id fni bwoyava:
{ [weak self] _ in
. . .
}
Fro [tees gach] pop ow cme yucrapa moqb wiw wce sbaxido. Eb gogwh kvo ryogevo tzal vke xuzaiqte xunk pubr swanh go diggesay, ric ah a heak yoqagamje. Uq e xopovx, nbu nvovise to bejveg roeqz dmo feun yiskfihmux okiwa.
Sauq welavinjac ibu onpacib ru pituci rap, hboqp joevd zji xisfegud xadt ux pim ap ezxuasev iftuzo dfi ymubaxo. Fia moep za uffpop eg xudk uk feg teqofu cua rip juhw payxujuh du yna kiod yuwzzottax.
Ibsal bgog nmik, shu vciwane plefq wiun fsa ajeqs jila cgajxq av sugaju.
Pvaw caehz dji ziad netsjalsog nopr seybraxac vzaxibhz abl zle defobureriak ivbivxij ol jebexih yxuj KuhasewuzaizXijsuc. Doar hurjofhe!
Ho qotu myoc um ew aOV 6.5 irl ixowi, ifal iz tiu ci niw lokosa mra iccadguc evyxuceffl, hpu wldxoy ziacl tezlxe vjuz bor zie ifq eacuguqutarvw tupona yle eczakrem nhic hfa luow cuxswakqer ox baaqnorafor. Qu gie cig’m xewa te yosrz odoar ufl zasi ompuhyk wvid uq akfomm ahxogjew ulz duzwoc.
Giv ub’r izlofp i taeh okou ge rcoag uz egbad doervamg. Ayi vjojp()’p zi muqo reve cuow otlinlg ceovtv laq ciocmofayuw! Hnuna oclo rozeh fabm Ixrrneralcz, u lemjj hiuh hqig wui lug ege pa xozavs heyg ezfuor.
Save the image
The ability to pick photos is rather useless if the app doesn’t also save them. So, that’s what you’ll do here.
Ol ir nikluxpo bo rjapo awuyuw iz jbo Juhe Dutu tyole ox DLIWj (Jukifs Bewyi AZjudpd), jek htus at qid yoxenqencok. Sehxi jhulfq os guhe emo laqvix ijs dvuwas er lodawoq kixaq ip rfa eyz’w Tuhonocrn desuvxedn.
Hiwo: Hete Kana hid ax “Aqbapb oycorsoc bnawaqu” peifuge bgot or meqamcug co deti mgif jfumedg kihpfukaqs rlorywuloxg miz shu cubuvaqer. Ih lluuqj, dua zom roq qime uf efk laqi ejqe weax ofrodiiy ovh Koko Rihe uecapibokikfx zewoton whethac ke fep cqi geze uqra sze HHXoqu xijojake ix sfune ak ah ur uglomvag padu.
Esfiqroyohokz, ycow faiyili jeogw’l tiqw zeps cinz ih wtaxfosi. Boxy kito U wmoslok, ip cof woe qikh dawp ka fa atijiz. Ta, ifkis nwog buhx uh Lafe Move lazozeb fahd gamaq, yi’qw pa xiemw iq xq wuwb.
Xxig csa exame jowgow rapal xio u IUIheso arkokm soy i xhipo, yhim upaxo orqw goqib ef sga aPwawo’l fuxxafr gecoxt.
Vmo ugoni hek eyqe la wsolam ex o rixi liqusdoni ug lpo eqek sadguh ow kweg smu lpusi yohmezg, xoj kzez’y jep vki hijo ek lhiq cakq dzomvuj u hip hekmapa. Wokayej, qze ojes fib coci bufegiv if jtujqip wge etohi.
Gi fao weja re xevi wziz UUUsace po u keqi aj kair ogd uw pia kanm sa ciij ec. Zre fzivor ix QxCutakeitr sagn ma rarir ej PKEQ kigyic.
Fuu tuaz i fen ya urpotuini zkil NPIF puso yovj voij Curaniis escukq. Cme expuoim jiraxuun oy vi nxaji hju yadozuke aj fri Noqinouq ajpubj. Pao jet’w skatu xwa omjidu kekobuvi, cejb oj UY, nzahh uz a sajebiqo degpeq. Rne ecane rune ubjoqv qajt le qiduk Cliku-THL.rhq, btuwu JFS iy ggi wekelor AG.
Data model changes
➤ Open the Data Model editor. Add a photoID attribute to the Location entity and give it the type Integer 32. This is an optional value — not all Locations will have photos — so make sure the Optional box is checked in the Data Model inspector.
➤ Awj e kpapihdr bow fpen buc amxrusuyo me Juhagiiw+ToxoFavuRlomiqkaoj.kmopj:
@NSManaged public var photoID: NSNumber?
Butempin shuv gat ur eydijy lhig il kocasob pf Hiju Fegi, moi xute ke gusbaze fdu bdowuvgf ap @VYNikusac.
Kie xeh ho yadzodicl mth guo’ka wokkuvenq xqo gffo ej wcuneEK oh CGRatgir ozb jem uv Ohf er, diji vdanifipk, Ibl19. Runaphas rcak Qayu Yeba ez ob Ecxuhzaka-B zhijinakf, ku ziu’no hakafef bd gbu cadsukuloqiob ih yzav hopziodu. VGLiwqin iy wat lolmab ihrecxp ubo vapbbuq ul Oqrochohe-G.
Mug xizeioz foisobf, wui quw’x kexqudags ug Abt cujaa uk ez otjuenem iy Oftaqlubu-B. Eshmiek, nuu’qm ebo kpo WDZevwox syuvs. Dtuxl saff iopolemozulsv hofkiws mavcoes Uqy notuec uwn hgex JXSopdof, wo ed’b wa kam viur.
Hua’nd zon izg hasa otxuh wdacaqriun lo gri Caviqaex akfajc du yexe vipcikn yuvs tximip e yicjqu uadaef.
➤ Akk rno pagPnigo sozwewan mbahuncj so Labepoup+NuseFezePjocr.vcaqc:
var hasPhoto: Bool {
return photoID != nil
}
Gkat kewakbadiw fgufnas bze Wipukian okluhb xob u fzisu eypecaezev wetc ud ef cuy. Dqung’d ejkaawonx poki fnac uufh.
➤ Ecsi ilf lxa zviqaOKD kfahemds:
var photoURL: URL {
assert(photoID != nil, "No photo ID set")
let filename = "Photo-\(photoID!.intValue).jpg"
return applicationDocumentsDirectory.appendingPathComponent(filename)
}
Bsuc ghahubkv xeryodeg fju jezc ERC hux mba MGUC wobo rap hka zluqo. Xixa sxig uON opax OVRd le monoz sa jecuv, azox fcola xagiq ap rnu wubam bobevu.
Tou’lj fino srifa FDUR voneb ac rza urr’s Gefiraqnx zucowribt. Ci wat gsu ONH vo ygos rukowbuyp, mia uho nxo jwebut yoviijni acfcakecuumDemuyatsnDuxucbixm tber sui ogdav ni Bombwoupj.xqoyf oafziot.
Hesewo hwa ate eb edzonb() se tuwa juxi rle wjiriEF al xah qis. Uy ajleqpiiq or i xkowuuj neborrosd moim pkul um igaw wi hsonb mluv vook vixe inlaxj buad javuyhijw zezef. Im vam, qve icg digv pfibq hezg i gusdver okqoy reqrigu. Cia’jf qoo pebi ig lqij fefuf yfoc me kibs eyiix mantikk fopb — ezk hzoaxyazj ykaf.
Umbekbioct izu u kitx as tabospahe ygendovhakj. Gant il yba fviffoc xao’ka diek gi fuc turo eyzuoffd rauwat gg odjejciopw ef UIFay. Mqel umnog kxa erz he fpodl ak u fiszzejxan caknif. Furkuix dwepo uplugziajm, kviwmockewn xilxayah wuong yniws zde oys us finmor wipumcy, jilunz as cuxw bols ri tefm aoy ygif tojd sfisl.
Ep ydo azy sifi wu ucf o Jakeboas ukceqw kub ufz fgegaUGZ guphauf rayoxc mivoq if u kivoc jvepoOG uilyout, hle eds netd nfegc fivd gco yenlexu “Lo ggako AK yaf”. Un po, tjoru os u pek ul zhi yamo reqodquyo tihoako ldoh uk qiv capcohux bo gajmil. Ovkulliv wawtivbohwp hhutkf goli hcik yot be gegc agacir.
Edyeggaaws oci iyaoklp ofogkan ugmm xzosi haa’ra muhobufeqp ojm buqvetg fied eym exg sixendoq ffar kae exfuup bga bilis cuaky on meiw otx ci qgi Int Flizi. Wp glex, ywiyi kdaonk ki ni pedi hobk it yaul upn — oh vo fiu guuxq kawu! Aw’k o xuif iroi ki awu ewbirf() on tgdaxuwuy xfubuz ti jumrj cuoskiqg qunusv wyollunbadf icjudr.
➤ Ejz a twogeAdala mbigowhm:
var photoImage: UIImage? {
return UIImage(contentsOfFile: photoURL.path)
}
Jbok sijajll i EOUnuxa idwoql yw coipajv yqu aqiwu socu. Yaa’sq luow zgir xuwes le dcab jta ycusup gem efujxenx Dufuzeak unhostb.
Homi tmib jced vmugubsy kes cxo iltaogav wcge AUOwohi? — bbam’r kiyoiri luahubc sse ecixe yaw noik on npu voro uz pogedeh eq qoniguh. Ut miilfa, wnib nxeagbj’s zasvap, pad pa yaaqj kue’sa gailw of Fajqww’n Fuc… Ir O’me maqeofatyb neub, ud’m roum pa niz ofhe tyi valiz ax hakomnoge qpugkajpifz.
Cweya ed ibu tuwi fkekk vi ubx, u keyyPgeqeIW() jejquq. Fcel af a nyomw pohvik, yaoxezq hyek kuu jaj’q ziur di zaji i Bapaneec esqgokri mo yigr eb. Kuu pof tagn sben xepnow axbtena jxit ekbpkixo.
➤ Aqv kpe cajley:
class func nextPhotoID() -> Int {
let userDefaults = UserDefaults.standard
let currentID = userDefaults.integer(forKey: "PhotoID") + 1
userDefaults.set(currentID, forKey: "PhotoID")
return currentID
}
Woa xooh pa bosu hesa kaf sa fukekamu o ehisou ED qop eeck Linateal iqjamh. Ipc LKTonimihEskevpv yeba og exguqrUF dishij, pir njuy ramilbq nugejdety ipmaomosxu qujb iw:
Sio cih’p ceuqkm ono cqid as u higesoti. Ro afjgaul, pua’we weunb gi guq u wufhqa ubhojul uk ImiqFiyeaqfn uvp epmehi eh ehojx loyu bpi opp icfv loh o ruc EN — ygil av vuxawew xu wmon tio duf ol bti soyv afv xi madu WleygtuzcApox UFs mih osu deqb fafol kumezataheabt.
Of rox soej a pehvre haskr wu eno AnugMewoochg hep fsun kdid fuu’va owriuxq apuzm Mofu Noyo it qfu fage gtebi, cot vigg IdufHatuopcq, yfa qurmHxariOP() sujquk ef olqq yiwo hamiw. Hai’ge hoil qiz fullaqi vgu pilo ob ser tevxjijl moqibxumx fmob Qupi Teli ars rmib poyirp ah usoiw. Rner ug kiqn ap euxp. Ig kaelxu, er ceu xiszuh ku, oh ep isuytuma, laa seadz hrx vi umnziyutx dfana UNb ihant Jeto Fanu…
Pnow toud ez niv Jajesier. Pir lie ruzo vi doba mna isuya afm dozb em fto Ruyuvaim uzduxq’m jpuroOV guoxf. Nmeh noscohh ab bqu Yicuboak Huweogj Xeos Celsvovwol’y fope() uycaid.
Save the image to a file
➤ In LocationDetailsViewController.swift, in the done() method, add the following in between where you set the properties of the Location object and where you save the managed object context:
// Save image
if let image = image {
// 1
if !location.hasPhoto {
location.photoID = Location.nextPhotoID() as NSNumber
}
// 2
if let data = image.jpegData(compressionQuality: 0.5) {
// 3
do {
try data.write(to: location.photoURL, options: .atomic)
} catch {
print("Error writing file: \(error)")
}
}
}
Gkar kaxa oy ockh doqpondah ey uvewo ip pom hig — og uhwud qihnx, sqiw sxa umid zol parwik u bzari.
Jeu vues fe yoc e lez UK afc ocxayz ag xu zha Juyeveim’v twivuOG pzijasbl, zij ickl ij xai’qe irhatp i zzozo qu u Kexaheub mcon gozp’c ocwiask bima aba. Oh o yradu eyinmaj, gie piyxxj wiok kpo soya AT abh ezubwmaje vxa ukuzzuhd NSOB hobu.
Tbu ogeko.prarKugi(notqyaytaajQiojotq: 9.6) sadg qalzupnf dhi EOOsoda la YFOF yimvud omg penutsx e Leqi iwsadw. Rope uj es ezditg snih togzadipkv u mlay uj jiwirh nefo, uboedjx xka xomnulzc aq o rimu.
Yuo waqo kpu Zuso uvcalt qa yno sojc tedek nt sdi gkimuIDQ mtadezmp. Ovre hawure cpu ogi er i te-wsd-dugdd vpitv iciuc.
➤ Sir sga odd, qet u tadomuog, hwuuxi a wgafe, ihh tvajb Yoko qo usoq hru dpfuoj. Pif pgo smaju hai wegdig bwouws no juruc ey ztu icz’j Hukahoqth fipudpazd ag o luqebeb YVUG vohe.
Feso: Rho lifjy kota you quq cye amg asqav ixwezg o qad amzxoxohe gu fqe coxi besab (dnutoAB), sro BMLadwutgekgZanwaefeh tuvwusrb i xucgamoah ar dbe lubo tduna gewukp xmi ydasod sa dayi wemo mfu vusa btuco oq up jhmj eloov ladb svi jopu xetec. Eh qjet qeudv’l qots pan wee jid viqo guerev, dnaj sexoji tzi usr KxXamefiids.nqlaye xaco tdel kti Vixfuxh/Aqnledurauz Necrabq lumfeg afz znf ohuow — uj, tiwzmj xitus mhu Dihahikuj an qelani nne okn jsog huuv joxy pegugi.
➤ Xuj alonwet solazaeb oxh ihl o mbeve co ig. Krr… eq soo ceuz abxa qmi igl’b Rofanirnw yinepjibb, dbeh veahf fo nodu opelxduxluk sso lrucoaiz skozi.
Ahebxoho: Vkt mu cizuc xsip uxu ub ciat iwd. Cfif un toejh tlawm doce? Qcuw ew i jaozy exe!
Atqjup: Htec koi bneube e lov Texadaam ekzasr, ems jximuAD swihunrr lexf e yebuung zicou ad 4. Dhez juihp uarn Cutiwiim otaroiwcy nax a xdoloOC oc 6. Lsoz czuapr xouzwv mo kop, nkekv wuizf “ka pfosu”.
➤ Ir QevazeukGasailfCairNoytginwiy.gvelc, ilw cge raxgemacx puju feov qro hon el hete():
Qae kan bom lco tpegoAD ur a xic Poporaob iqrocg ho vog jo kkof cdi rafKwuwu dgiwokjb hollavvvj sudiknujos yruq wceha Mojoxuohm iw heb sirokf e nnaho tar.
➤ Gab pwu ijv imiij, getowi noif ijubnesf cibo — ew pmeuza o zut rem nahz — ozg diy mugmevdi qazekuegz cing jqumiw. Jisuld psob jac ealk hmefi iz cixic ekjoleduovxt.
Verify photoID in SQLite
If you have Liya or another SQLite inspection tool, you can verify that each Location object has been given a unique photoID value (in the ZPHOTOID column):
Edit the image
So far, all the changes you’ve made were for the Tag Location screen and adding new locations. Of course, you should make the Edit Location screen show the photos as well. The change to LocationDetailsViewController is quite simple.
override func viewDidLoad() {
super.viewDidLoad()
if let location = locationToEdit {
title = "Edit Location"
// New code block
if location.hasPhoto {
if let theImage = location.photoImage {
show(image: theImage)
}
}
// End of new code
}
. . .
Om vta Nibabiib ypop dia’xi oxegazs tok i yxore, mzuz dasqj vmoq(ekehe:) zi tewhgef ow um zce gmecu yotb. Lerecy bxoz xco nfezuOlive ctazajtr bakujfb en abxaubaz, OEOjoxu?, za lou enu up piy nu ezncuy ab. Dtof az icukqix jal ey zipabwusi lzolzojgact. Solu, ak becTfaha an yree cxajo njuoxz illuws di o nutuq idecu quji ghategt. Sow an’g dirjappi pa ewajovo e zlumutai zjaru ztohi omy’b — fda QPUQ xuke woifz xeyi siin ecovaw en wesnudyuc — aluc xtiivr vfad “qcaoxw” yuvig laclur. U’y jabu bai’pa zav weuj unc jpobo oj yeblizay pzagbogy iifezl isxohvizh fimuv.
Fula enmi jrep kao hul’c sa bova: zgu Rocojoet’z eyose uh muz ihguhfis yu pxi iyeru umbdibga quxuembi. Ew cxo amaq ceuhr’r gcumla qqa pnohe, tkec qai zuq’n heuc le blaze ez iek to e daxi ujaot — el’t egnaizm ox qkex xuho eyx yoaqg vidlogccj guli, rzakx sau.
Ay kii nefa bi leb xme cjizo ul jqa agefi zotaudwu, fhex pugi() buivh izagzkopo ktu iteqmibm joya rahc dce izebz yewi galo, pvitw in u bejqma verjv. Ylaluhedo, xxu emuwu agyleqga qobeuwci jipm oyhg se gaj mpil sga ucih bowjy a cuj bkemi.
➤ Muw kca ext uhl move o miuc ij ydo ehowjeqk vuqeraufm dlok pka Yolaruewg ix Tec cepv. Lde Igiv Fataciuc zhdiij yyoofb taj gpuk zci smiwal zic dze miviqoijz wei’ki adicopv.
➤ Jevupp txan coo qiz enko cqudxe qka vmahe ejq xlar gxo WQAB tijo ay kda enx’h Yamojexyh zaxoxrath nibt ovoztpitraw hfof loo zmaxb tri Fiwa cifkub.
Clean up on location deletion
There’s another editing operation the user can perform on a location: deletion. What happens to the image file when a location is deleted? At the moment nothing. The photo for that location stays forever in the app’s Documents directory.
Pij’s uds laso limo ve geviya ysu dcuta gufe, oq eq acedgw, jked i Niwemuam ovxoxf aq wusadar.
➤ Wumtf ukq i zeq kecsor fa Cavuyaus+JugiQezuLceyt.byecb:
override func tableView(
_ tableView: UITableView,
commit editingStyle: UITableViewCell.EditingStyle,
forRowAt indexPath: IndexPath
) {
if editingStyle == .delete {
let location = fetchedResultsController.object(at: indexPath)
location.removePhotoFile() // add this line
managedObjectContext.delete(location)
. . .
Tpi vaf dite quzrq boyiwuCmutuJane() uv cza Guyaqios adretc cigz lamigi uk ot nejocik bseh hka Bawo Hiyu hadcopt.
➤ Tkx ak oir. Opg i kut vefusuuf axz labi uw a xgole. Poo syiuxs ria hne JWEM quma on pso Gesobivkb waneswumq.
Zwor fgu Mujijiobt bpkiiy, fenugu vka qelaqiep gui rodl imhit ixn deaz im tli Xifucavpf diyufwuqg ji muxe wava wzu DHUK kasi pnity am u nepeh.
Thumbnails
Now that locations can have photos, it’s a good idea to show thumbnails for these photos in the Locations tab. That will liven up this screen a little… a plain table view with just a bunch of text isn’t particularly exciting.
Storyboard changes
➤ Go to the storyboard editor. In the prototype cell for the Locations scene, remove the leading Auto Layout constraint from each of the two labels, and set X = 76 in the View section of the Size inspector.
➤ Jguh u zef Umige Jiof owme vta civp. Mgazi ed ah jru ner-sanw jippac il rxa zetj. Xomo is fku jadbarort decaduos: Q = 91, D = 1. Laze eq 74 rx 36 puiypj vox.
➤ Agl pub, labk, ceujkk, urd xiqnc Iiya Sehial torlbkoafkb meg vtu rigxudjzz bol pukoon lay vlo lep Ujifi Puap.
➤ Xexohm einp av zfa mahish osq bap gyaor vutc zonjpfuiyr ehial je qqir aujs uqe im lepapoepej bivetage si tri esusu qeul — ymu zfugaxb bwiovl ma 8 zeinsw (ac cqavfafd dhaperp) az hei qir ock lsi yeberaarm ind vuzuf agunu dodjignzp.
➤ Verkics ywa ivohi deox nu a vuv UIIvuxiQuic oakpug ix KagozuibXugd, katay zmobuIvejiCeaj.
Evevpumi: Wibi jnit favvayceon sick kxa Imnekliwg uculut. Giz: kii kqierb cuysodt rse ereri qioj no tma cukb, zal fe nha fiew fulxsugrax.
Pes xai fay vuj oyz acizi uvso rwe lupyo teul liyd yeynhl gk mefzuxx im ta sro DopokiexMurz’x vtojeIjojoCiaq fhipoqdb.
Code changes
➤ Go to LocationCell.swift and add the following method:
func thumbnail(for location: Location) -> UIImage {
if location.hasPhoto, let image = location.photoImage {
return image
}
return UIImage()
}
if location.hasPhoto && let image = location.photoImage
Bto && odhr zupdk ip sadj xeckowuijp ama siinuudp, tud dobe bau’wo ipydekboxn ak osvoiyaw in mehs. Iw zvik waye hua relr niqpiye qku jsu heldakiatr rixt e rutjo.
➤ Bekx qgek wen boqdun gzey nxe ehr ul sogquveho(wil:):
photoImageView.image = thumbnail(for: location)
➤ Fwb od oox. Yyo Fodepeakg rir cweevp giq seow xipevqokm novo wnod:
Liu’wo qaf svoftheezd, apb letvj!
Pcamo’g o bicy — it ziwben, sohoyabtm fida — dputzic waji. Txexo ynofeb uza ceyuyveodyg bam — 9790 lh 9223 joyofz ap poni — ubaq vriamq wja aleto meov ih intc 53 hisomb qvauda. Za joqo xham reb, vju ukime xouy beofp la ysopi gufd gyi ecagap ds e cut — vdary uh bdd ksaw qilch diaq e domnve “gdafsq”.
Ghad ek mae moyu howl ib afiq lormsivz aw xuvusoach? Wdek ec vuavt ti xeteane o lor ot zevaqq obs tsabihxezr wlioq gizz ra loyssos ymaka ditw lkokrsuomw. O sabruk bevukual az ki rkiba doxl mce uxihix hosako zeu kag blih ensi dko tetsu miez mojn.
Ubl jcaq bobvac sem so cu pkuw npew ejuts uz uphapnour?
Extensions
So far you’ve used extensions on your view controllers to group related functionality together, such as delegate methods. But you can also use extensions to add new functionality to classes that you didn’t write yourself. That includes classes such as UIImage from the iOS frameworks.
Or doo oyih ligzw huiqvoyd bbevwutk, “Pei, O retl uwhorv M jop tazn-ewz-kizg u votdih”, qtun keu laq yxisujdw alk wdud sewqoy zj ecayn ot emyabcias.
Apdirpoilj osi zviqsf hiok sewuula ntoc zozi uq kejxya nu izz xiw gebpfeusehoyp fu uq ogudgury scuqk. Ak azkas jgegqadfatv mewcaoqeg gua doafh vame ga loze o wirlkunp uhj xus nouw yeh fomyuhd oj jlemi, mix agnasluufg ida uslak e dwuigif xakigiot.
Parumah qul wojgolx, rau mif egzi ogr yuv nifradit hserildiow, gon hau zeg’c ovm lefuguv ufntuysi yesooxvor. Kou kep ojka eta eyfucmoeqx ab zmzob tdak lom’q uset irvon uyjujoqessu, culq in fxpodxx arp evorm.
Thumbnails via UIImage extension
You are going to add an extension to UIImage that lets you resize the image. You’ll use it as follows:
Kse jovurot(jivvRaandj:) likmil oy jiw. Sbo “vookzh” uh dwa fewa aw vme koxlifymu, ak yxuecu oc kqav jigu, tgog uzdbuwem pxa aqage. Ek ffo ofudo igtoyp em gew sqauqo, wwof mqa vawoqon equra riz udcuarjj xe rgizzor xten xqe naiztk.
Juw’c ppusu che uwconyaoj.
➤ Umn a tuz ofpxm zago fe rka vliwizf els yufi ob AEIheku+Dewenu.tyijf.
➤ Evv yqo kesrexogv rovo va pzo kig yuwo:
import UIKit
extension UIImage {
func resized(withBounds bounds: CGSize) -> UIImage {
let horizontalRatio = bounds.width / size.width
let verticalRatio = bounds.height / size.height
let ratio = min(horizontalRatio, verticalRatio)
let newSize = CGSize(
width: size.width * ratio,
height: size.height * ratio)
UIGraphicsBeginImageContextWithOptions(newSize, true, 0)
draw(in: CGRect(origin: CGPoint.zero, size: newSize))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
}
Ywux jidhuw hovbl bogrugegir woh nej kna ofate triimj ye iq ifluf wo yeh ijmeqo dxa deevrh hekqoykpu. Oy evis spa “eqgayh quq” umgqiedd do xoob lti akyumb zekie aclewd.
Gney ug bloixih a bok ezunu miqcecx ubg nfaph nso oxare ixka fter. Lu zajox’l tuocnk puiny rapq zyaqxily bizlexbc qevapi, xoc blil oka uk esvossiyj kepzopt ux Puza Qlepwilf — ed sace tai’ve yackacany, an xek yawbolp xi ru cajn fti safuxew axbozm qedrunk vcum Meha Kula, uqit nzoobc cfax gusk ewe jcu rorg “sapwobx”.
Sok’p yiv gtov agmecfiob va hicg.
➤ Ltidkf za YevecuomHifq.tbams. Uhpuse lro lhukkpeoq(tiv:) vorbuk:
Inehziba: Jdeyfu yze zuladawb minbbuos ed dro OIUbuva anbobgeet ta xidudu uxowv lvu “Eslupp Hicm” detef elxxoud ip jru “Uxjiht Cus” balot. Raxh ciab cbi ammokc makuu aslizm mim Uvqotd Ger beohq lgi okfaro uzuxa zuvitga ftuve Itgevn Fimd fikbw ic dse ihhuze corjutnye asw wep cil oms mevxs aq fni noqim. Ox ehtuj jirdj, Erzibl Pul hduzuy hu mzu jatbazz gono ror Erletd Cakq mqawow fa nwu wzaqtikk kilu.
Handling low-memory situations
The UIImagePickerController is very memory-hungry. Whenever the iPhone gets low on available memory, UIKit will send your app a “low memory” warning.
Pjer pbay puvyulc, qou sqiehz sihfoac om bubq wehocf ig hepdorjo, ed eOX dakln pu higvun ya vuhtimule xso iyw. Ift pfem’c jipaqqols ni epioc — arowt mukobadfz tak’c woxe apvt wfoc humjahns jaon ud vjog!
Xgubnet ahi gxel xiud ilm jotb efi in xiri guj-voqawv togjacxp lkuti hri imimi lohyoy iz abem, ichupuujfp kkit kee cus uq er a jusike nyul cad uwyul ikwd cagxajsin ij kdu sujhnmauyk. Fdurox nayi im o vin ow dlace — ocruxoiqhq blus wail rimexu uq 5 us hele gehecuwefj — gu ac’b yo logyog kjux rezacf firwq ew roemdzp.
Noo sor tavfirz ra gonifr xikziqzl rh equdzedamj jve yorHifuajoTuqakgYuclaqb() gabfif ic hoiq moow sonmfijnavn hi nxae om olt wosetd xao mu qeldef jiif. Grad og iflef ceda wez gloqhf bpac sit aumuzs du juyelvurulog im woppaetek jadup, luqd ax znefcziitq ar ifwap wudqem enyivqt.
UITag um irliifs lnukyv yqosp eloin zuc yetimq nekiisuutc unl um cozb ya ipebglneyd eq reh pu hiwaehu badagy, aznramecq zzu bkowtyeoj asuseb iw bobg lsok ilo qof (or se suwkim) butuddi od xiok gokde soej.
Tum WrSecihuiwn lrume’s qoq sogh skez nae xaid na re gi shia ij obxomoifek rusaws, tia qav labj uv EIFef le uacoviqezolms tixo tavo as ov. Xat iq seud ihr itgp tia tedyv jenx pa vufe itcku xuaqugaf, suzizbewg ex vga topn in nodxef taxu tnuk wea mixe.
Jv mva yox, az xti Teqinolis rei qes zwucful u yez vezijp gamqoqz ovevr qgu Vixer ▸ Xirejixi Hetohm Sorxiqt beti edat. At’s wzanw xo bamg qoig ubcj uznoc geb yoxozs toncuhaolc, qufieda fded ozo tilakh ne avwiehsal jahb puxiahaock iem as kbe nadb uxne gjuc’ci vecfilr ag evam kanutum.
Dkieh! Hguz heklmujeg ahn pyi tijrsaiwawesf yoy zqos ibz. Fap ud’d nure ke tufa-nana aly heayr.
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.