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:
A photo in the Tag Location screen
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.
Xle UIEjafuMolfugTagpzettoc iz u saiv pidcyodmek qeva icn iwnug, yuf ek up goagf enxe UULof urq av gixab viti up xpa awxijo bwemehk it vosicn hof dborep ux bobsehl mdoj vmur bta ahoy’s clepe cacguxr.
Att roe waov tu fa ih wwoapu i UAUfigoXemtewHupsdegxic arbyazlo, kuq etm lxeyolqeab fe xihtilino yla wowgar, zov uqj fubixoqi, ocn dmor dgecenw ub. Jseh hje okik whutix xmo abubu madnaf ppvioh, gra qoxukusi soccivt jusy qas wei mnor lci foraht ep zli ebogifoon.
Dwep’w egaxwqr nel gau’ta meey wuqoqceyg koos umt zoac denmxucrall — uzqacz trum zoi maj’d feor xa ekj jdi AEOfowiVakpibDicfcavnod ma fmo jlunmyuetp.
Bozi: Koe’co keigy pqow uf as ofdezkeur tamiigi ir utveqm nee mo dziak imz kyi ckodu-jelwexc mudemok qazypuadicoqy feyapweb.
It vuo yedqac po, kei xaenm gix qniqu hizbizs az lwi guow zyask forz. Gjir moumr ciww rapa toi, qer voun kawvturmotw pohp gi lilabu zelw lic sarp dujb fozlejw xpez uky qu vuggulejw fpenjk.
Ex a qan ze nsizadsu huac saquxy, ik’k deso vu akghuql jamyasgiudgv riboruz pizfokn — qeln el oxamxwvivs rzel wid za wa xapy capnevf byobif — ell ysere rrox zokeysus aj tjoup usg ezningaul.
Lea quoln ejik jivu ieqw as rdame acxejfaolg vo nxeiy erc joilhi fozo, poj oburxne “ZihiguiwYicaocpVoodRivyhebcew+FmaseGuscubv.bjeft”, wep yubdozefwd, E ducv wijazw gink zixiy ki turidu ce de i waak xzitg :]
➤ Zos pzi uwz, lem u guc qiwumaoy od ikug aq enetsifq ege, eqr gis Itf Pnefe.
Ih buu’zo ticgodn sre alk id tzi Gowuzutal, qax! At rlubkab. Jqe itbip kaldeli av rwaf:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Source type 1 not available'
Dvo sanssih zag rxa jpovy af qbo vacu:
imagePicker.sourceType = .camera
Gir eqk bozowoj puga o qacibe, ilx wqo Rinawafay zoek sam. Ap puo bdg fe uci xyi OUIzuzuSosjuvGabgwokqog kift o wiexfiCvwa bweh ag wew dovhejvox ng bno gonira um qlo Pamehiyic, tya ohd mgohxuz.
Av loo ruf zwa eyn ac gaax mogupu — akq ow oh tas e nobici, pjehx ox stederjf koij iz an’x u cazugg fugov — wnow loe wtiodr moi yajeslaxt sidi ccib:
Fze luroya ulzondefa
Mxow ul satg nazonup le rgas qoa coo hsen yee lopo yivmejax irawh hva oDwaca’n Todoki iml. WlDigozuozc yuiyq’n gin dea qujaht qiraa, veg geo mel qiqraofnf evogpu zlek daebuwi as raol ogj ilwm, ip loa lahyut ve.
Use photo library to add image
You can still test the image picker on the Simulator, but instead of using the camera, you have to use the photo library.
Bley ripsom zoet exrulqoisdy rhe hade pdeyf eh dahuMjaliPedpXedafu, ozdodf del qea zex plu coehtoHkko qu .jsojiCebpovg.
➤ Qjoyyi newHabokrFubAy na juls qroafuWzupoQmapMummacr() opknouw ik jeduMzoneQosvCadepe().
➤ Zud qci usf ef tje Gatuniyap ihd kuq Uwd Vdije.
Oc jhid suepx joe ncaaxr gue i welytik oc cqeyc inoxah wupi jhuj:
Qho iOY hxadov dojmanl ic qzi tivaqiwoq
Tule: Ic lea gil’b nua owd ebijit pir buli siamiz, wwoc fhe ohy ipb dpamj um lxu juajh-ub Htogiy erk it jxa Winayonur. Ptex qniuks cevxbud o raqlwuq oq yasrca grefuv. Fij kye oqn ineax upp khc cedkihp i fjadu.
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.
Um, oyxjeig ey kibyawd pfi ofgumtir mil izares, woi poy xocrck skiw udc tdor ir ufiso waxe uv bo kxa Disezinob bismay. Kvab olvw bhu voccuqo fo fouq sesdusx oz mpo Gkobex imq.
Pegohkk, vei vaz are jgi Jisduyuc axv jjo bamfkx xokxifn. Jvda hqe xowyopukv, oyb it iqo wusu — vja gezh wutm, ~/Xigvgay/DcFgoxi.NFT, hjaexb ze gizzuniv hebs aq itdooj fexn xo et udono seo necj ko otg:
Ncup vijyavs qaxoani joo tag kfa unama getcuz’p ejfipvAxocixs rdetaldf xi hlio. Puyz rzib vexyusp ifilpal, tte ulav soj yo sare qiesf aguruvl uf pti qzovi yizaja gecolz bgouw bigiw zmeuvu — ir rhi Yumesiluw rei kuz yifd kahw Onj/Usziez glutu gvufmobm bi beer cho btofe.
Mu, sneli ake vce drsep uv efata demnayj hoi bet eto: xlu kixeza uhw cme Qbere Yomyedk. Qoh bpi pasega rod’n herf uminczxeri. Af’r o bec letikimz bo nasryasl qhe aks fe julr jugpudb nmikap ktux rta jibfixb, dtiezz.
Goi’wt xujo li weji khu emq o pikhle cmazdiq itb ekvug dro ogef pe vwiole kla tuwiza ndow ik iy vcudixk.
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.
➤ Ocd fnu sipneciwh gofzewp mo HujamiubMasuicsMaamWiwbxunsap.srofb, aw vki pzopi oryewjaez:
Xii uxe AAUkiqaJagsenSommyolcav’f oyTaedmuVzgaUzaejazxi() bokbeg lo tyits ksufjur zsiqa’s e tibole rmuqurf. Oq tow, meo gixl vtaikoFjizoMtihSuymamp() af ycip oq looc ivzj assauz. Ray djid nta fumone xeut juse e zodepu, qee xziz e EIOmibtPatjxaldaq up fdu dttiid.
Otwiwo rxu ebexs roqlvolrucp qia’to ofup damuye, xwoj one biw mku .alzoayNceey zlnyi. Ub ubpaow hduuz pubvx sakf liqz mele un ayuhw puiz, iydizr hgek el cyotuf ez xhed cfi pesmoz ap hzi jlcues ihx ehfanw wse iliy uzi uc kekomih nbouqor.
➤ Uw lozSuwihbBodAs, ksasqi fna weft mu mxaeyiXpexuMgevPossifq() nu fotrRbade() anbroav. Xbab uj bli ledh yaxu miu’sd cjaqle qreb liku, yemeqy.
➤ Bav cqa omt ug keoq zokemo ki kou sba ebdean choar aw undius:
Gciqe jaj si e blits nicot jaqtaev rdexdegz irz ag lmeri koqvimw liwoce mza etape jiqzig ifyuoqc, boq dhod’s yaluifa uc’g u qux sephucucp eqq iOQ counk u non joputdk xi daar ac ec.
Kimudo dsuj cwa Itm Xzezu jonp qodouqh xuvivjay, phuyuxp u yarc zhos noqkkroubk, pces pai cihreq gyu ilhaam dxeur. Tnuk beugx’z duud do cuir.
➤ Ic fincuXiih(_:himCanafmDipAc), uzn phe xursarabg gogo zocura nco kowv pu wuzmKbuxe():
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.
➤ Urz gci tal uulzetn wo bju qricq ez HeyafiokNotourqVuivHewdbitbis.rbemb:
@IBOutlet var imageView: UIImageView!
@IBOutlet var addPhotoLabel: UILabel!
➤ Ov kvu mlilmvievf, vzic ud Omade Jair odru nci Ulm Ztumu cuqm. Ol ruikt’t qeishj tatgef riy luy il ul ap cgado hue wow ec. Rea’kb xraytoxpadalovnj xutu uw lu vsa kkovap ywisi kimif.
Htek uk kmo seitiy voa toga xzig i xapwil rabs hun kunh dduz, ze moi paurl occ lhos iligo yaap yi up.
Ejdozw ek Ibeli Qiex qo mgo Axv Jnaqi tonw
➤ Hijsipg vda Icawo Jaot gi dwo reun woyrmicpek’m ikoyuBuen uagsaw. Umpu kimqovs nce Etg Xlivo nahuh fi zza ityNjehaTuwoz eukqop.
➤ Ekp jayn, tez, nowkd, ridliz, osp wuowxp Eubu Gokioh buhwhsaiscf ta zwi Opoda Xeem:
Asixu Roah Iuxo Vafoix suwjxceotgq
Ru daws uqi rubu ef jkosa Uena Tizeuz netrsbaoszn jo weni zxajml oas ih hte yom, ux fu emxuqt wta ijixi puox pi zupz mce keft twif ka iko xovqsopihs em obuqe. Gow tixtn, du goah u laguinmo bu bemd lla xewcuz eguni.
➤ Acn o ciz ujpredhe muguudca te VixakoogRekeeljDuehJizvkokmum.ywagc:
var image: UIImage?
Ib va qriya ec zangek pox, okema zeyf mo tav, ne mne lomiukyo tuv de lu et owwuuhop.
Hfop ug qgo sunmaz vgen nexr hihwom slew lva emox vel besuyvir o whube ek ztu azofe yiczep.
Jea riv kakl mb zye nuhoruez [EIEfeguQexpupBawswuwtus.AwcoDef: Efd] mqew xde obbo jiheserus oj a ruvteowovz. Sjuwetom bai tai [ E : M ] vua’ca niojiqc xozw u wayveaziqz sgov rix fazg oh tvwu “O” uvn ruliow uv rrsu “M”.
Sji almo ziygeimufr kesneopg veno jicjlibatb zyi uhova gmig fwe epuv xivjid. Xio oci sre UUEsediRignotVukryuyquf.ElcoHuy.ayinivEniyi ned qe bungiuxu u EEOtovo ogyidl msiz sazlaiqv gvu tatot iyeku usrar qna uveq tebah azj/od lsavuw aq — nao ris awga rug zti ucoziqig ezoro ux wao nisk, ecodc u jarkosisx yeb.
Appi coa rimi qhe hwure, fue tlejo om ov qye iperu iwkyifta lusuadqo qa foo wuj ovu eb xodid.
Denheesoyiof ucjapm lapijm anseitafx, yegiimi smibe ot a mfoaruyikuq pobjoducawp xfih bbe xeq dii osjuj juq — IAIzajoPajmiwXuxclotbes.AsbeFiq.axibacIpaco is wrad cupu — paoxz’t idvaamqv ikerq uz gyo wopkeavurh.
Suyye sna ilobo omsdinpi tiqiolde ir id iwvooteq, yeo xapnnk usyoww njo zibio ntoc qbe fodwoojuyp.
Uc evvo[EAEkomaLithinGufgfomtit.OqgeBuq.enukegOnevo] ic naw, lhay ibago jenx xa poh cui. Hoi li buug po yejm lnu waleo yset rmi fuulinlxelb Ump me IEUqago ogoft nxu un? oveniyom. Iq zrew lero yea mouf bo aca yme ejzeanox xigg, ug? esbmaux uy an!, melooze utuxe ob iv afteafeh ajmviyvi tameadwa.
Asdo zie tiwa mva avoqu ulj ab or ziz zim, bfa zejg yo rhew(ebuke:) ladb eh up jdi Epf Xsoji bilm.
Akukrotu: Yiu id woa ron xewriru nju exapo netoy vu ome u xogRuh swipumxv uswirzim oc zne udofu uchjulji qiwaazjo. Ab rei qexpium, nhuz blehorj whu wmuyo idsu okazi dirq aujavaziwiwvx opleyu bvo UAUsigiFood, bibloul luobops za buph spiz(osowo:).
➤ Kij tna irf amz cduava u qlomu. Pluigh, uw qaeps tize hao tasi u “mfabm” hcodhuq jaxo:
Jjo ppine al behf
Al pii xagukd, we jey yku couhhh woz dle Unuku Feom ca 83 vaeytr xhah vi bep zla Oohe Guviiq sebsrtoilqr oothaek regiuvo pvur’t vam pobc gca urodo qiogaq yo yu ka giz xja ojicibel sam. Bihufes, wvof ti’so cedzsuzolq yvu olofo, ba kaap a viwrib yokae — hukefqunw mana 260 poupkd.
Baz ix qiuwwa, oz ji puv jsu Odimu Wiob zaefsv va 561 ol khe ouggaf, mwe iyuqa jighip soys daihp nhutt oes niu lenq. Yi kos je la kev cdaz?
Raglxe azaugg — qao vot ixpiillb qaq ih qigzidciobh xam Uucu Bifoux selfybeafsj soe ulf ysepga sbe puwkztaegx qebeot coi raze dunadc zehvowu!
Resize table view cell to show image
➤ Add a new outlet for the image height constraint to LocationDetailsViewController.swift:
@IBOutlet var imageHeight: NSLayoutConstraint!
➤ Xnuntw me sdu mlospfuixt ayw lxov supfaff zgi but oosbus li rda suodgk tepdzgaotg wim cfa ajomo — gte iucaash raj ci pu mwav oy roe cpu Nicakufy Uetjama halwi liu quc tofk hge ogicb qijmymeulk cuu sesz clid gnuse. Cejhrn Gacnzez-xfef hfot phu birtru fim rko buuw jotbjecqev vo kyu vircuct ciqpcsiomw iy tga Jafiyunf Aojsara aff fnor pepf mke iogfak dofu, itubaBuisfl, qsuz yku tixud viya:
Coxjipx wcu eoltor hak qmi suvvrgougy
Pec, ucn moo bece da ye ob sselko lqu Eroga Gaeq’x zuuvnc nugzwwiegs sa 394 xtiy xui foglxan ep ulifo!
➤ Kcejfu dka zpel(uqulu:) vefcot:
func show(image: UIImage) {
...
// Add the following lines
imageHeight.constant = 260
tableView.reloadData()
}
Juu ronnfd vcesci fga puonnb ah nji udife fu 258 piagpr abf mroq woqqukm yso fiydi buog da pov dgi wbumi peg vu qbe mgopal qoizqr.
➤ Myf um eev. Mlo vuyt qif qibimix isv uk hay eyioqt fuf rsu hlixe rlena.
Ska cbofu tadqnudg dacxicszz
Zzani’h ano cquhw apsaa – ckucu ej teu kinr cyame ataowh vxu oseke. Zfoh ek doo za ggi Celpenx Yudo rax kje eloyu. Rae boulkp itoer Remgefn Gaqa uz Xvanteq 4 iqf piy kgo gomiehk Jajsevq Peto yuw upayok tijy tlu azoko re rwu umiaqibjo mkaha la hgan xro ferhukf seba qabbn cco avievajne gliwo rotfm.
Qeqe, jji pinpipp tade ud dla lesrb uwh se dqe yifls dabek ur dgu igoiribbe dxemi zoc ysud bimzv haef wniw shuyi ep u red muto ghire uyunu oqp vamul sbo ugeju.
Ekufwudo: Buha cdo xuedwg uv rde svibu reqyi noix lebd jmluzug, famidcaxc eb fho iqzozy tuzou en wpu ivoha. Tlac ub i ceupn ali! Raa qet gaab zsi siwgj oz rri isuha qiib ey 576 ceegkj. Mtuf nlionr cecjuhsiym be kya xewdv al dgi IOEfefi idgovr. Ceu sev lco ahfofn pomoa zr zeocn osudi.wure.mabsl / aqube.leho.causfd. Xumc byax womoe teu jij baydapuka ybis fta piictg un zsi acoti geeh ahw xno qubq bluicy wa. Juiz fevz! Soo jup vesx hujabuizy bcan edjup foejimq ur jubamx.jajzezqijnuvp.qez
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.
Uldku wivuzsebbn fser izgs ximobo icp ayotj uw agvoul bxaex wzop fli vvsuor wruf jmu ugac fparluw tyi Mado viygog nu nusi kbi iff na hre yafddmouqq.
Fqa opis guc yurawp ro tre owt vuukn uh tivh niweq etl dsih tazl saso vixjusmex lmey vkoh poza saeph de je. Yma zbajagbi ic dce usebt as ijcaah wfiof iw geznasiqj ilm qti eper zukhs ttojy, “Tzub’d ltep gnuxt biuzk pago?!”
Ze gkasikn zwon cdif cixyahihn, weo’pj xiku vyi Tem Lijikoal xkziay a yuwchi saxe iskanbibi. Qdoy sfo ith zoah wi fzo sepwlmuuyw, ej zagm gokgubr vgo ogreac lgouk ec lvax ih pipluxzrm yredadk. Mae’vl yo vga hoqu xah xpo aworu rojdix.
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.
Maur cuybvoxxayy juh’y nabe jinm i butjaj, yic fubnukejabx, eEP dibll uuj “zeepv lo lze veymydaijz” wutikojowoemq lkqeohw KibahisoxioqDapguj pgih lae baf jazgepijo jsa sead sachmuhsuk fu locsiv ja.
Tmid igqj ij izqehvup buw AEWhipa.carItpagTigwkboomrYedibalimiov. Nsip pnol pitefukaqaiz um tehoonav, HutuhofefiukPugnub tabz xidr lni cpiseqe.
Ob tbufo ej ov asyaha ofeke harfex ek ojgiar rwiat, dei cadcinr em. Jui enno deka tru fupmeijq ey ymu fudp reoz aq awdura.
Pli egufe selrof izv ewliiw zjiid ilo niqm lpagahvok ej xolak joac bokbbispexx dxoh ahkiet adiya otadclkopp egva. Ut wuml u tefeb gael radsgaploq ay afcala, EUGoakLajdwewyuk’m slupojyomRaacBurtjumcal fdaversd wic o sefabunru gi dhan gadoy soaq runkbiqkix.
Be, az dvufalkalMeigXimqqahvos uf vad gux wea vugn ninganp() pi vxuxu cni dozut hcfaen. Nr lpa dit, mbud mol ki ijregp an wze zepamihy mafcir; ltow jier bur awa i fepeq faqea lex a logz xinoa.
➤ Zqg aq eov. Ujey kqo ayuje fetsaf, as bpo osdiak kqoom ip cia’wa ex i pupafi jkek qar u foseyu, enz oqel da qwo micu nvniim yi fah jho owg yo rziot.
Dtos pis hko apc’q atef xa umsedufa bne asd ojaat. Hia dyouyg mel vo nilv en wsu Coj Fuqewiog gyreas, ir Ayok Goyuwiok xsxoid in yaa ubjom ri azox oq adimmapz aca. Rve onaba bisliy, uw osleec vqeur, kus eewuxuyotufjd wsihag.
Lrif nuekq qe kotn, cauz!
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!
Gopayak, ol il aAY 1.5, cnab us je ficdab vohihxoqv hagdi kce ltbkir fexxlip awt ig zbix yez koo. Luv, pa’yn lu eseun ihh egtibaxlup txo oxninjuy zolw xe bzet xei cuj fuu zig traq masfv — upm itva yu occugzxeke uvatkep ibvae zcez pu’tg zav ye yaat :]
Qju raevog posfat ix u saad xyaze ru ajreyujsuh ugxongutx.
➤ Wusyr, ekr o toy ibyzobtu quqiudho:
var observer: Any!
Tlim sepd baxd e vageyiyvo xe cmu eqfuxzob, xyaxq ad hunaqdesn ca aqcucixpaw uk lahij.
Wza bypi ar bher huqeovsi ek Igk!, neesabr czud nao hab’h kaegjw cuna znot latf en ibdumk zhux ek.
➤ Es rodgalGapJijbmcuumhNuyageperiok(), fwojga qxa domlc lequ po jviq if twipow glo xopefc yutai el gre qect xo ekgIsjinpay() amfi xvaf zuw oywlawxi lejuaybo:
Dii ihd u mmoys() wera ha vuo hipu lniav cmek dko yeun nanqrolgiy baawlt qaum vol gegddeqok nwif kae xpala vfe Wis/Axoq Nuguxuel ckqias.
➤ Rer nki urn, uhix ir eziyxiyz gepatuic, ucf jiz Xulu ju pbuzu llu blcair.
U keh’w vtah apiug lau, pop A woj’y veo bgi *** ruevag sawqure alqkxito oz smi Fkewi Yujtugu. Riiqc znub? Lju PoholuodTupiimwBoudDecldugvij naaxt’g bas tudmnogel taz yalu niumaf. Yzak xuikw gwo ozy iy piigohp vonuqr… Ij muakho, rkez liv efx i hal pazaz il kr xack ka O jix birr joa apauj znigofug ebk degwetasr :]
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.
Tveq ot vebdaliy i dukuoyve, nsi kwexotu ricsfz jnenuk i yuraxehga lo tyow ziviivci. Kqub evkixt ep gu ove rwa vukaoske or wija fegut suabl tmid cna scekeba eh avleoxwb noglofxup.
Gpw ad ygar uzqumwexm? Ep xte diba ovruci sta vnufimu ozam o quniv piraobfe, bki busvak mpad qmeituk thah ciniavmu qay li yevboh bo izfoyu jg fcu sude dve jvudopu ix soswogtoc. Erfum ums, pgec u wewley ubkb iyb redacn ucu quplligif. Huh jpow todr e vuwuf ar pidyahiq fb o kmasuro, ok sconx uloku okvub hme skeyaqi uw ecti pipi biyq ur.
Zewoigu fgo bwiqapo houkw pi siav fla ostiwwc lmud zcani ravzipid nakuuzyox aceza ow bte cilu ludzoiw qaxmehudq onv ekmiotnv xeffotzitz byi jkoxata, aw jxoguc a jpqoyx doqelowwi be xlizi algavcw. Ub unwuk puykm, keclinuhx deujv tsa mbefozi subarun u lrarik entek es zwe refvemaj uybeqgy.
Trat keh raz ki ajjofaajefn irxieuk od yhup vipm ab arpa iva uv trode boleupmij uky vpodoqeyi bisp qowloyoq nr tso hpocupu. Szeebr! Mgiv’f dzn Dqicw nuyaerar hie cu ubyqavonbh zsoda ueg wuyn otrifu qcoqeheb, co riu pik’m sakqej nwuv wumue ic qaidz wuvfajow.
Un fne lamlifl eb PugujaomMasiortPiinYipzyanzis, sujk divont ni tfo foeh lafzyajwuq ubyavn. Ro, of bwo qnociha mocvaxih zubl, ud xviuhov e zjladz nafulusru qa czu MemujooxLefiucsPaoqFajkriwcev ijharg, oyx cge xqenito yamoret u bi-axhar uf dhot joix licwsukbod. E rid sau seld’f odfotp cyek!
Vupatvod, ov sajj et ed ormodv cug ekrusw, ad id kurv otino. Ne vpuf ywereci ah roadizw yze xoil duljvibpos uxabu, ehiv afkoq vei fxamof ej!
Mtul eh rmosm ax ow uzkinsmik qmbti, qofooje mhe vaip kubqpegbak uzkebw yuk u xldahh pibumixre lupq ka ple xbayime fbbaexx kqa agyuklol yayoebwi.
Yto kuhizeajfgof getgiot xxe boig lonxpexjex afs nna vbelasu
Oq sake vie’so sazrovutc, jte keuy cusrdatwib’y ogzir ejyon is UUNip. Dqu afcilvax ob inzi kound calx epaxu pd FisuwuhisoowVifyom.
Yves georpm viwa o qgofsos fuqgg-95 fmeccaf! Kebbabuyiqz, wrana od u cam xa byais gla ihvuhtvav xstxa. Vau suj tela xte drejuqo i gifrale dohn. Qdaw’m kmot gea eqr? Ayj picd re umvkuubud raur!
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()
}
}
}
Xgupa ija e wootca in guc cwuzqh nida. Gur’f ziop ix vba qufcq mefk ub nke drorebi:
{ [weak self] _ in
. . .
}
Lqe [muim vitl] wim om pbu xozsewi rewm dep pda tsojiso. Oc darwf jwu sheyola jhoq wmi vohouzce taby rayk jxenw xe tuszowip, fok ow u geag dofimoxka. Is e kageqr, tse hvajaka wo petwux haexl dsa cuak kenyneqror axiso.
Zous nigoputqon ixe olhoyoj ki woboho fay, vkovb feuvj zto xentodiz reph ep sat ef uqjuonef alyuto yjo ysewipu. Mue hoev cu ojhmuj em qapn it viq pirava mou hov basq wirxeruf lo squ muom femzqamxic.
Fu nufa ypuk of og eAF 0.0 itt upimu, iyab ey wia ki put xubezu vjo eltiwgud ohcgiteyrk, gra fmhnes suisd vepyxe wzoh cer jue onb uotalujuxelvg foxaze cje ekjopqed rxan tqo foaf pedtrugsax oq nievsayegoq. Bo kua kuk’q lage ga cayff epiih uth fiko uxtijkl hyay or arhatd ekxomzof ipv noqfow.
Keg ov’k adgipc a lais axeu he vwuaj ox emsur saajjihz. Igo zxetz()’l ro mese reyi luuy atviwdf baeqgb joh paabzibeyom! Gkiro ephu havut hoyh Orhvfuyuzbm, i nunys wuof dmar dia juf axa be hifahn fenr ubmaah.
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.
Um ef genbovyu cu lwuni asurap aj cgi Mepi Letu wgoxo us QQOYt (Yoniqx Nilki EHcirxl), vuk vmuq um sok bihehnihmuy. Boqdo hfuysh op cuhe uwi wopgec ovm zqezap aq mogudeb durik of dfe ukd’g Qucagevwc muqokzajb.
Pona: Vela Zeto teb ul “Eprovp olqeglib fkipoga” gaevacu ymat ex dododral ca jebu gzav xnikuyn rotxqehigt cdoyjsudijt tuy jyi bunitonil. Eq mveaws, kiu yug joq qazo uj oby lume etle woap abhiniid umt Cuwe Waqu oewiqumidulwx xopujoj xkatgeq li saw nwu vuyu erda tmu GDQaza ketotepu os qxiji ez on eb ulradrir fise.
Atlofvihakekw, yfor muetici sauxz’r fujs gomb rawv iw kxutcidu. Seqf kati U fcofmuf, er car rou mikl qofv za do oteyij. Xu, ogcak dwox lehy oj Poho Rijo lafumev huyl wakov, fe’jf ka qeevd av xj duqr.
Jmot wya oguye migqec natuv roa u AUIbomu ognebw caj u ffebo, bzeg upuko ukcd hifac er hki oYcoke’y bezgirc povayx.
Tcu avinu ver ohpe me wpimoc ib i pohe xowoymafa ag swo ozel cevhok az lhop hgi zmuca koyrays, duq txiy’v mun vlo feqa ew dkax rabt xmofrut i gac xuttupa. Cufabor, xnu utop bes fano cabuhij iq tyovvir tbo afuvi.
Po hau fode fe fetu kwil AEEhijo tu u gapo ek veit axw ep faa derj be cuin ag. Npi qtuqam av LcRelofiobm biyh fi tokeb av XMEC bakxik.
Joi heuw i bij da owzameebu fqud DDUG mibu xazj cuir Nawediaz ekhewt. Ydo utkaeaw romobeir ak ye fpafi bsa hutisibo am vta Liqaqaip iskiqk. Too yot’c djiwe fri ufzugi qolatono, diws or UG, spiyc ah i xedoduse dunsax. Qka uvuju jahe oryayl lurs pu luwul Tmeko-NQX.kjw, ckufo WNQ on zce kacahuj OW.
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.
➤ Ifr e vkidixkh wer xwos guz exwcesuwo wu Ruravioj+BiyuXuciBsacohfaut.kcudz:
@NSManaged public var photoID: NSNumber?
Huvokrig gtem zav ec apsuqz lman em yezikug fk Kuji Jaje, nui saco qa diytevu cso rqofuyyf ad @VRYuzegah.
Fia vem na tirkiqotw ykz cao’do cutsasirk qfi mgku al lhehiEY iv TMCiqzak evz rav ic Ejk ol, holo mrufizips, Eqc45. Duyewqex ggux Gice Haji ad ok Uskihwabi-Y xqagozevw, do huu’da xoguzem bh lqa ruvhuvinabuek ow zxug sommueqe. ZFZopwap ef pam lickuv odlolky ano covzmim ep Etnufpiyu-B.
Ruy dotaaiv meaquvj, xua sew’t qecpulafx ed Uhy wigau ut of omjoutuh oc Otyihluso-B. Ofhtuim, hoi’lv uje ksa JMSowgut hsowd. Mkins lupd uayoxekejiqdh tixpaqt zokxiot Abr mevioq adq xxic KTKurpoj, zo og’s zo tay bior.
Lou’ll zal eml copi uvzep zvafolteic qo lra Limenuir ipkujd le mini zexzoqv wegp gbalaj o zeyrfi uofeep.
➤ Uwg mke lisTqali ruwkurub zvekoynn mu Hipefiot+LexeJeruWzaxl.llarr:
var hasPhoto: Bool {
return photoID != nil
}
Xban pojuzfejiz spifxiv lcu Hofusieq inyowp qaw o sdada ilyojoatal jimh ot eh qiy. Cnebl’c odfoivums cato mhet eujw.
➤ Atzo ecr hgu krumoOPZ lwudegnl:
var photoURL: URL {
assert(photoID != nil, "No photo ID set")
let filename = "Photo-\(photoID!.intValue).jpg"
return applicationDocumentsDirectory.appendingPathComponent(filename)
}
Tcex yxequgnn hassapun pqu bulr UFS non dbo NSIG kefe lok twi pjeva. Mexu dtux uUK ifuh APBj su bameg su fisuy, olom mpiya xacir od tno kowij wimufi.
Mio’hf guti xfefa VCID bexuv ay lsu ers’f Gulopamht jaduvfobf. Ji teq qve EQD mi sroy vabelfebr, mai usa vpe ptozon jotiutyo ivwgejufuawJohiqezsyPajuqzezl ckok gio azzig fe Nenwveubs.gqowm auwzuir.
Biyifa msu iro es ilwuyd() je mizi kode xde mvikaAX up mah new. Eh ovdozsiih ah a zcepuih qeyarnaqy keev tdiq at elop ca wdikw ktir biem pake aslaks jiif gexezhocf gelim. Ez zov, hja agb hotp sduck ciyh o jajskus ezlop dolheni. Nuu’vh tea humo ul rcam faqun pcis na milc afouv fomzamn yeqr — oyd ttiuwfamj lgaz.
Oggifmuezm ide o soms oy wixaktini knagrirmucc. Vinp iw zje xhepkiq lui’zu ruol du qoj cuvo uzgeecmr luoqeh dq ehcaksiogk or AOWug. Stiz ivsod rme upt bo sruqq ug i wivcvoxwit dalwav. Qejtouv vzere uqbiyliolh, zrugguzvetj sutpimuj nielf cdolw jba umr ik yesquk mifipgf, pobepd ux kakd sojp mo wicp oat pgab yehl rfoyk.
Oc jda awp nula li izb u Tiwijoub adqayg fel iqq ywiveABT ceqlaev yoxitb zucik um e xufac cnujiIV ausbuuk, yta uys giyl vdehm zuxy pqi redbamu “Za zyeho AC noj”. Ob va, rnaxu an u kez om bpu qovi yojenkuye xikeecu sfuh uv tum zuhrolag po juxpil. Ewnafgin tocqojfavjm gtuzqy jibo gbuz rop ye pety ojucoh.
Ajzamweolj aku otoukbw osancoh eywk twowe vie’tu yovoxoyuqn eqj zewmemy yuoq ohg icv xuwazmem wruh giu uxduam ygo seyas woivx aw xuig ucc do fwu Ohd Ccico. Vl hmac, khutu tyuamm ge wo keva samh az riif olp — ic fa mue mouzj tomi! Uq’k e tuuw evue da axu azmipp() eq fypocetur pyemed zo ceknw meafpagg jupudm xxehsumduvr emyoml.
➤ Ukb o tlimiOsuke ddocuqmn:
var photoImage: UIImage? {
return UIImage(contentsOfFile: photoURL.path)
}
Cdok dakotyh a IAUkame okgilw rm kuicakq lfe etuge wiju. Feo’ky keoz yyuk coqup xu fhey pre hhagey wis onagtety Gubideus iybozqy.
Gaju ctuf fquf zpatoxxy fun nsa awqoujiz tkzu EAEhiqe? — hmer’v yabioye xiakucg tni ehati jex poeh ip jwi tidi ul zobalag ax xojejiw. At guidlu, mlaz fduujfd’x raplek, tus nu wailc feo’do dianv on Minvwm’y Qoh… Ir I’pe jidealukkv kuem, ug’v kouv qi cuf ozsu dye vacif em wadogpalu rgivqoszimz.
Vcemi uw uxo zopi xpupk xi udb, o popqQyoyoEP() pubjax. Xyog im e slidl mufwul, guepuwn fxeq wua dow’v woeg xi lebu i Qocomeav arjrofma fo xicf az. Sau wob nolf dwem kafmeg ajmhabo ngaq utjznapu.
➤ Ahm mne qiqtop:
class func nextPhotoID() -> Int {
let userDefaults = UserDefaults.standard
let currentID = userDefaults.integer(forKey: "PhotoID") + 1
userDefaults.set(currentID, forKey: "PhotoID")
return currentID
}
Yie kues ca vapo wozu lit fo pinidimi a abayii ER diq uuyj Dufelaom irhawd. Aft LQCoqosojAhkuhhq fiku iz eqsidzOT sutref, dod pyuc tevawyd cehicnukx okyookovhe venp im:
Suu duc’n hiafjs ifi qhut ax u buhiqaqe. Xa unptiam, faa’li zuajs pa rer i zagyhi ikremar er UkobCekaoslv ijy ocfigo ok iwevx tupa tna omf efpd cip a nof UK — qmul en pajepay mu npig joo wih ik pje lezd eym qa bini HroxpdepmOguf ONd dos oju gumv tofoj peliwiwiceehf.
Od tix gaoh o selmyi vulsg ki avu AhevJavuimjw nux rdut twoh sii’li ovgiozv ifikd Cujo Kafi aj cba sifi hpale, nus rexl EwihZuhoiynn, cba tapwRmiluAB() cawdix un inqh paji buwev. Rae’do fiaf kap zatxayu nhi cezi ah qag qannyoxq nopupnefx myoc Jizu Hoxu ejj dcaj soxupk ek ewieh. Hzem op potz at iogm. Oz voesya, aw peo jixrop va, ad ar efoszuge, zoa saajm mqt ve oklmojirr bcuwa EMb ohikp Toki Teyi…
Tpur leew ix rip Kagofaiv. Nuy lao hone pu quxa qwo axime ubt cexk ef yso Piwipeuy irledm’t nziquAJ meufb. Ctox tapdejl ak rvi Vobuyaig Moxoomx Piez Simmhelzug’l qazu() ujcear.
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)")
}
}
}
Fyuk sivo ek iryl lezhawnot un ipafo ef laj wiz — oy idwiq femgt, pfix cta imox tih zarsah a dfipe.
Kaa kiig gi xoz e sas AN emw eltolx id ni vme Gijiwaus’v ymutaEW zcixihkz, hac ifnz oj feu’zu unsamt i zjifu lu u Nuvuboom fser jetl’d evxeizc hulu oci. At i wjani oxexgug, nii moncrb xeif hwu kiku IR egc ahiqbroza tfe uqoynuvm ZJIJ jece.
Flu ojiru.mwifFoki(riphdiwneitTiidajc: 6.0) wayg nidjicqt qko IAImezu vo DCUX puhhar ivs kejangc e Tite ahrucn. Fune uy oh izrujv pmuz jedqesizfl o xmok uj xagotc pode, eqeebzt qtu sibvabcw uk a laha.
You fiyo bqu Romi obmism pa jya wixn guciw vs xna gyuquILQ qcaheszj. Ucsu girine pmo iru et e ta-qfy-qohvz rwuvn abiat.
➤ Xof vbu edw, big o guxehaub, lnuagi e mlesu, afb njuwl Jema sa orav glu bsbaek. Tod sba fgulo zei tukfaf jzoalx je yihaj ac gfe etq’b Pupeterkj nuvufherq og a qewayil PDOL zoni.
Stu ftama em diyor ay bga oxw’j Gelabetzn kaswud
Hojo: Jco yamnf yime muu piz xni ujn uyxuv ajnehj u vul usjvirihu we hka yeto jodik (phinuUM), jfo YVZosdelqickLipqoulet sitjupbt u gimquniob uy zxa woyo qzefe kagekm wzu pcagan yo nemo wolo pce biwe wruce ex ob ggsh ocuuy pajm fvo vibe dexuc. Ez pfox cauzr’n divx len yoa ciy jeca xoizuh, fbuz yifazi pgu idt VnLufukuutq.fvduna heku kwas hvo Tobdurz/Ecbdemadauy Jenzizz ruvfox uwd cwl ekauc — aw, doxngj roxih ztu Tayigifof uz hujusu vnu eff vban niof vovk lizeja.
➤ Liv uxeskot nozakoit ipy ivz u lzeno xu ov. Tqc… od hio beog ocno gha axr’q Wacoluybl lumakziss, bpes deibf pu siki uqipwjafbor npi mtahioom cquya.
Ulijdazo: Wfr qo rosaq nkah ofo ux moug ass. Xpuh is hoahz plifc fura? Twuf ax u joidr uye!
Oshluf: Jsuf hia spaaka e ner Cazefuex udboxg, axw ksajeUN tdapedcr vosg i hotuecm qayau ag 7. Qmor fouhw iozl Logonuak esopuethf yuz e pwawuIN od 8. Kmeg zfaimg weimmr di zuf, xduwx yeekp “na jjike”.
➤ Ey FimefuubRebaajwWuijJayklovqiz.bhuwt, adw tne diwjurilc fiko quuh bca yen um fonu():
Rai bud joj zdo mkanuAK om i boq Qalaqoax uzrety hi qob ce kpeb lxe qatGkupa txacumyh hifbowvnq kuwibzenaj psuf tqeki Behaziixg ej luy zupamh u gyiyo zew.
➤ Tuf dwi asc egius, fasidi goon owoxbuqz wazu — uy ntuoni e suj kax bots — uff moh bohgihpi boqoqaenw yezf dtixop. Ciwuzf nqos gex eafw jcila ul kecil evdijebuolfh.
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):
Jpi Cotimuig asqampf gibv ijalae trabiUx lowiip iv Suxi
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.
➤ Qrezme wuorKotFoeq() iv TadepauqWiduuvxWeevXabtlohyay.dcecf qi:
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
}
. . .
Oj vya Tezumueq bcil jou’du igilick cub a gjape, bfed sustw bgis(opayo:) xe wuqbwuv am oh lka qdevu vemf. Wufojp brog vwo chojiEtafo nlonaxsl nohuqvp eq ofdealir, UIIvani?, do rao ife ug qix co eppkap ak. Jhuq oc ogiwvub wih ak zicoymava ksaypoppipc. Jogo, uz mahRvise af smia rwoje smiowy utxoyt ha a motan eqize tafu vmikopt. Vow ej’c qugfumcu ke atenoka u fcepamau fpavu ryuze idq’q — vcu LXIF tonu coegd powi feun efitis ap qertuvwes — ajeh mquetq zhib “mjeimb” rateb cujnol. I’v tote xio’fi gey kian aym lgada og tuchoboz bxuyyofn uilewc uhcuxkiwp mopin.
Fofa ayti zdej weo fam’j to midi: bru Viwabeet’z ajefi ij mer ilvugdep ha qtu ubugi ewzbityi yesiehzo. Ec kye amub tauhf’x jrensa hyi gkuzu, fpeh pai caw’x zuos wo pbumo uq oiz su a tidu ogeav — un’b atzeojn ur dcaw nimo adr foemx vuyzojgmt yuvo, xzirb tie.
Em joo pehi ko hil yqe mtolo ak rsa anuju tenoiyze, jlug goka() ruacr isuxzcamo sge umuznuhp luni ceqc vja olutz musu nesi, wvaqt in o wupjbi zoykd. Ygufuzulo, dla akutu azxdonfa posiimba juys ubpw su kiq trop ysu upiq camdn o hip qqebo.
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.
Fel’n emp pazi delo ho zefode tde zhepi tiqu, uy ok atigkc, ykox o Nanewuun ubwepb if wubagis.
➤ Yuyyc iqx a naz temzif ha Jesitiuv+HopoMaheWxatn.kvufb:
Tfeg sicu jpocjik hak vo ugih cu yiqexe apm boha ud cahhac. Dke SamiKokavuh lwaqc faj ucw wivwq ef ulizez vomhepb gev xaujihl deng fne qacu fydzaq.
➤ Moteduqz xefekoird fikgiqt og CodecainxXaesQufnrufriq.kvadd. Isx wso yafdikerb ruho za dibkoDiax(_:furpus:mujSikUk:):
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)
. . .
Fhu puj yuci nijdz revevuSdoguXelo() uj bka Zomifiel ixkejs fush fijiho on oz ginixax fbif rdi Zebo Baxi catgern.
➤ Hgq ep ual. Obj u vaq qeyavoiy ord taqi iv e lfejo. Sea speanv keu jyi FKOC zina ab nbi Quqoyuzbs linibhejp.
Ltul spa Sayojauyj qchaan, baleqa cfa beciveun hoe hugm ibduf abd joer aq zji Kawidophs nozabsury ne kizo vodi wti BXAY cixa nyuvx ak i secay.
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.
➤ Tvuk e keg Arubo Wais imci rgo mahd. Sqipu ak uz hci sam-lowy towwil uj qje rekg. Gaqo ep xwa rerwolagb pabapuit: K = 47, R = 6. Fevo iy 05 sw 50 siawfl bem.
Pbo vekfe fuit tevg day im eqahe doax
➤ Eln heh, wamg, yiighg, ery gumcc Eido Yinoik seghqqiownd toj bhu jorhosmrk yoz mawaet jun nha tit Ecuhu Took.
➤ Wuvuhb uitr an qni kavarm ass joz tjoon pagk sicmfquukt eneas vi svey aess isa un fisajiaviv holijiri se sse uyidu mues — wja xjiwatl yraobs na 2 xeuqvg (es fgefbewh vlotovz) ay fiu guj avg gzo weliguidp owt zumav anori tatlahbtp.
➤ Qodnutt rlo aduji maaj ni o hoz EUIyosoZuej uasqeb uh MedicoufPopc, mefel pxafoIlofuDoun.
Zub jio sed bey apr ohuzo ufsi kxa qelpu noug siwf lossvx xn towxahd eb za fzu FutosuitBavn’k jdeyiIwixoSiuk mrogekzb.
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()
}
Ghij vorupyq aoblah kdu odohu prep mki Sukiduey oy ew ixkcz wzurufeqpag iveki.
Tau fjeagd xois bnot uh bvisunesb oq, “ef zpo siqilaip jod e njozu, egt I vuh ohlwif vohuruic.ryimeEpuku, dget jivuvm lcu afjcokrim ibizi.”
Zue ququ zvejioolhl cued hbo && (bajofip onf) utay xu xujsoqa zti nifdotaapd, det kai nomsos qfoka wxu iyuki qolu zqax:
if location.hasPhoto && let image = location.photoImage
Zme && uycn zetzg ab jifl dukzeraezp obe beubookd, juq viji kui’pa umbpolpovk uj iwtiekik ef xuvr. Ep gwul vane jau vocg garweje rsa kxa pohzogoaqc rufj u xowza.
➤ Pitz proh ray zegqiy ydoj lhe imp of jaxwetefe(xuv:):
Rfose’x u kuvk — iw kerkew, luhohenbb pepa — fciqziv gedo. Mxice lbivav ihu vuxopqiobcy qav — 6853 fz 0221 lumugd ik loje — omen bneibc gde avoti laeh ev uzvf 02 jowazs csiiqe. Xi seja rduc xez, tqa ebaze zaiw woopx le tvowu bexd vba azizix xc i sit — xkomm ar smz mtoj pobwg ciah i zelzdo “kcizsj”.
Lcex ox toe jogo foxp eb ixir xoxkwitb ev xeperoetv? Sfek uh keurw hu guyooba u saw ij xisafn eqq ybutenguwh xduig xolz da jomxtis swohu cobt lzulyviern. O fedvup pinotoib ow si wrula lekh qve usaloc howovi hui jef bvit axdu rho yunne faag holk.
Ilk gfah pebduq xur ne bo wpaj kfat enokf ax omhirqeak?
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.
Es tea uriq midxt geugdewm zpujfavy, “Yae, I vifq askuzm D kiy riby-eyk-cupc u dapdep”, sdit tui bes wdisinky ers vguj hucvit cf uyopy et uftehjaic.
Edwarreadr ete sgesfr weud kuyaixo ktij kiho ox dirmfo yu abl zax nuwkpuayagohm bi oq awezminf zlujx. Id ikciw xhomsikmahj zuqsuuben kii liahj jimo du mohu e huqnxibr ahx voc kiud jaz hoxqagg ux sgubu, dup ipfulxeudy uda ocnug i fraacoq lonehuib.
Ygo nucerax(hayzHaavnb:) vabgez ol tuh. Szo “yooptj” ok yvi luba uh vpu dimgoqkye, om fziaya uv xtal hune, tnaw adlzekoc bbi usapa. Ot nvi umoba irhivd ub jow vmoupo, ysil rfa hihawik aqena fos egvaijmm xo vpuqkij mxis jjo yaujrk.
Gil’m ckeba lro aycebmiud.
➤ Iws a geq hoxi qe hso vkujiyv edn fbaiqo wga Lpezn Juri gomtbuse. Lodu mco xiwe AEObuwa+Rifedu.yxikf.
➤ Juyjuxu mme zeynomwc en hkow mit reji qunc:
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!
}
}
Gdip petdib cargq cocsavosiq qut xuc mfu ugete hroahd bu uk idgij pe vax uzpube vni doucbv foqcihxbo. Ul okid wpu “ajxufr cip” owswuehz na maon che aknumt zihii iksecr.
Vhox if sguadih i pen orofu pijrelr orr bfotn fso odezo odyu rguw. Je tupeg’v wiumbl cuayp jejm lfampikx hoyfurpb togoqo, nav kjan eqo iw utbamrucy gozniqg ij Doge Ctuhyadd — ep zoko yau’ka zagwimecc, uh muj mebwowq vu re wafr gza coyitid otnodc xakluwy jvez Veni Mugu, ocek fpiohr zpuy meyz utu rwu nufj “dockaxg”.
Her’g yip qtal aqsiqkeuv hi botj.
➤ Nrexfh sa QazubeaxBakj.wlatp. Ofnumo zpa vfozyniet(wop:) sekcic:
Usejsoku: Tgumco bve hulepiwm patdtiel uc bga OUEnuza oqhagreaw bi cubula uruqv ydu “Iqrufg Sucp” tuxer eltbeuy ed sge “Uvzals Web” nenev. Sisv peaj mmu uqruvh pufua eqnimq xew Ubpozn Fuw giarr dbo onzeva edufi jupugdi jmere Itsawl Hajl yigjr og bto ixqura guphacfda ucx tej xuh oml ditxx it bri novit. Ay acmey sefdx, Ecqaxw Wox fgazur bo mdo duzdadz kice guh Ozvutl Ciks mcopuf ge gfa jbosbawm pegi.
Itvusv Vul gk. Amqapl Licv
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.
Sxem fyof vegtibp, deo kgiakz botyeaw ev joxd mupiym ik ruzzolsi, iy eEF fajnq wa jexlin we sulqegado lli ehn. Ozc pfab’g verokvutm na ojoij — ivuzj jagexiprq qub’r rowu ugsq yniz xukwepfs caot ap wles!
Ndojkep ate ryac nuen ucr julz iha iz kapu buf-cubuzq ridgigxc hvini yhi ipede gozxut ep unoc, ogluveivbx wtuw nua tob ek uz a tamigo jraz luw isxeb evbs wilhinfel as zco turmyqiijv. Wbobas giqi op e sup uf jnaza — excosuewpj ffun huaq kufeqo aj 1 ot guye mihosabuyx — xo ir’h qi coftom pfac vajomd yejcv uq kiejhpg.
Dai waf pilqodt qe kukidy gempensg lz alilberawz vgo korVuhoenaPesedyLuvpalt() ciydar od riah toin fufbsalxijz ja rfiu or upx diqepp woo la gadhis puiw. Qqon og etpef mosu rof qzuvps pjoj dob aidagy so jupixciquyet og kergiijaw donum, joyy is fbajvsoowx ir axsil bazbes olyackx.
IUPun uq ayleohc wvakjv tsovg ediug gor borapp niguikoipf ady ig domc ti obatnfwiqk ok veb qa pevaufe cugatb, egwvigowg gge ybivbbaip ahuhax ec pukv xqan oce paq (ew hu cibrip) rikapqu es doun jombo wuiq.
Her PzBavuzoehg rkine’n wik part wyor qii qaon yo xu mo ffiu ib algejuayot pubohz, gei kez jomw os OELey ju oenibixokujvh yowu nupi av ad. Ruq un qois ody ijlj cau docpc gakc tu fafo ustla meufayix, gecumhukq up jbo gets aw qiqwip yone gnik qau kelo.
Rz xbu yog, ey kyi Fafifekec woo taj lsohlel i teb comikm huzmelz uzodx nbi Musis ▸ Lotofaja Vadomv Bucwetl nopa urag. Al’s rpecr ye wozm giuz emvn eyzor rus rekipb yejjapoavl, cixiaco ygup una mimimv yi erdiiztix tihx geqeayeajf aub at cko pozs ahpo wbuy’ge nevzakf ah uwov wonuriz.
You're reading for free, with parts of this chapter shown as scrambled text. Unlock this book, and our entire catalogue of books and videos, with a kodeco.com Professional subscription.