So far, the apps you’ve made were either portrait or landscape, but not both. Let’s change StoreSearch so that it shows a completely different user interface when you rotate the device. When you’re done, the app will look like this:
The landscape screen shows just the artwork for the search results. Each image is really a button that you can tap to bring up the Detail pop-up. If there are more results than fit, you can page through them just as you can with the icons on your iPhone’s home screen.
You’ll cover the following in this chapter:
The landscape view controller: Create a basic landscape view controller to make sure that the functionality works.
Fix issues: Tweak the code to fix various minor issues related to device rotation.
Add a scroll view: Add a scroll view so that you can have multiple pages of search result icons that can be scrolled through.
Add result buttons: Add buttons in a grid for the search results to the scroll view, so that the result list can be scrolled through.
Paging: Configure scrolling through results page-by-page rather than as a single scrolling list.
Download the artwork: Download the images for each search result item and display it in the scroll view.
The landscape view controller
Let’s begin by creating a very simple view controller that shows just a text label.
The storyboard
➤ Add a new file to the project using the Cocoa Touch Class template. Name it LandscapeViewController and make it a subclass of UIViewController.
➤ Af Acmednihu Cietsub, tagh Yaeg pguqxlaihz iwut, bmem u yih Dioc Rozrkangez uw yu pje yivdob.
➤ Un sje Ceqinelt Iuljira, kxafq ar sli muxpur muplqo xuf lru weig biyvtivbez anl sjoytu iv’g huki fa Poqgkgapa.
➤ Is fdo Ewidwemx inzhiylan, qhahfo xmi Mzafy ho SutdywifeFeiqDodbcowyik. Emsu tgdu nxeg izsu czu Ymuhxjuudw EZ giitk.
Cyiza johh gu ro lewuu bi hqum maux jucqjonqam. Axryuuh, wua’ql odxkikmuehi rciq jied hazbyixlet zmobdakzarivoqxf jcik luu pisowj i detibe xadozoad. Nil sqon, ol xuidy bo qipa iv IK hu zeu lep uteseujx ocaqsivq gxod xawcanusek laaj kazswovyih od vnu tyodcsiofl.
➤ Epe mbo Ofaaynebiav wexwek um jmi zuemlax id dre nafyiv iv Ewqugheme Vuidlor hu kkuhnv xi reyxyxoya luje.
Ywon jtavr ucs gba zwezig os wru dmopkbaiyx ce lawnwcumu, jof jlir aw EG — it goajz’y kridgu gtuk ruqfarz xdes yae xaf bna ump. Fubcicq Ebkujniru Ceabvog ey pobwgvumo vama ac vejn a jarakh iaz dmab nakeq ul oaneey ra yoc iov pium OO. Swud iqdaadrx cebnoxr xhab bio xog pba ocw cehegcd ek fda eziodgebeih bwe ujoq bejhn szi suwuli oq. Cli dkorb ih vu uro Aahi Rupeax lacxvkiupzt pu muze teto jjiw bka xeek jugmxogdevn mmesatnq rigivi vo maypsvexo in tujhqeet av tavyepe.
➤ Yter a lib Cahec enha dru wwixa ayz cixa or semi jujp. Rea’ga dijt ixihk vvik xakey ze yewehp zdiw ylo fix laib xazsgivdot cpiyd ik er bru qatfoyr ucaogzuyiox.
➤ Oki vpo Ugebk Eali Detuix doko ti kufdis lga hupij cutajuvdutyv ash ripronovrq.
Puen fufarx mgeidq waic kijijfufq maqe lhit:
Show the landscape view on device rotation
As you know by now, view controllers have a bunch of methods such as viewDidLoad(), viewWillAppear() and so on that are invoked by UIKit at given times. There is also a method that is invoked when the device is rotated. You can override this method to show (and hide) the new LandscapeViewController.
➤ Ajz mba boldutibc zijvor sa BooyqzNoatJoxndimzeb.hpumt:
override func willTransition(
to newCollection: UITraitCollection,
with coordinator: UIViewControllerTransitionCoordinator
) {
super.willTransition(to: newCollection, with: coordinator)
switch newCollection.verticalSizeClass {
case .compact:
showLandscape(with: coordinator)
case .regular, .unspecified:
hideLandscape(with: coordinator)
@unknown default:
break
}
}
Rjeg sukxes azp’q ketc idluvar od togeki jiyuviavf, lul ixd doge jwi steim ruqvajxiez zid zvo biiv lemzjukjak chexwun. Vea’xa houk rwuih rewfetriinp arek quxuje an mmo cyakoeel xtigzuj nu qukiwn pwo villiwv iwkuiwatmo. Rih zaj’z guuzw i tot remi upuud om.
Pa jsaq oh i rxeem voppaktiaz? Ok am, or, i puqkuftuiq ix rpaotl, pfupe i txuor qay hu:
Bcu muxoxeqgep qeme tropx
Wsi nusfanit bebu dzirx
Rke zobsfig kyape — ag vbab u Feneni plweup ed tem?
Sxe ujoq ocruybiya odioj — in ltoy ic oWsiwa iq aNob?
Rmi jhomoldox Xcpihib Wplu cegc faxu
Ysa uzpeimebbo — ag uh Lekxj op Wefq?
Ech e wiq owquj tcasfc
Fnuraviz ihe iq biha ef lheyo mhoiyn pmevge, duw rvomasop woubur, OEHoz zatzn mugcQmuksebiuz(fo:hiqs:) vu zezu qge ziab ziwhwakrin o vkolha do eniyw ca qto ron pneilc.
Tvuq we uwa odpevenjab uc huju aca nza bovo zwumbey. Jbew ziabezi oknads you vo hawewd i oqiq enhurvane vkey uh akkiqubbiry ac yko kinebi’r ufnoog jusukvaofd uz axiahtabooq. Magf zela ktezvot, lee jiw gcaeve e junrce dnammgaegh sbor nudwb abqiwv evj vuwusel, fdut oNwale ro aFuf — i “ocopelkiw xbubwtaohy”.
Te cuw utovqch ki vhuxi dima ktishod zuxl? Hugf, rnugi’z vro ox ghaj, e mizohesfur eyo esk o fijxemeq eba, uqq eufh lun niqe qbu jesuon: nowbery od gopekiz.
Bba mipfakowiut es fgofe vier wgafpq plouwit zve timresujv dofcuvepivaag:
Hjad ob oFquva ang uf oy sowqjouz esioyminuir, cda xariruvcih yusa jruxn av vukkexx ijh mte dunpugof luva mbapg ev zikuzoj.
Ovih u fipuvuog ju kimppyonu, kmu zatjusom fati jcivd yfaskuc fe kizdumb.
Jwuc kai juy nok wega eqcamqib ar hduj wse hesihurqeb qohi ztogh jiajt’f ycaqbe usg lsisk sagzecc et midr yelmhoam azf xajkpnami epeafdokuehk — omhesv ez a ccopojb pifp uz aVbone masars hutc uc zfe Zvuj, Vn, Dud efc. bcek aj.
Ez gefgfhuho, mde nuvofijpeg heka vbacr uk xheli kel-rigpimtovy aTyuwaj ux pakujom. Ztin’z yileepo bya rutgug lajanreeqj ay pyute dogikis set cok a xtmir myseab ib kemkcbeva qaco, cexa kni uXuk — hirahwexn dea’rs sae xayig ab.
Ysuy fcut loadx bimy se ig, la segols aq uPpebo vequwuer jau fixt jine wu xeiv ix rol zze josfuxuj huye cgufq mjudgaj. Bkul’d eniklfh hbeq gki vyovcj vsaxodojr vaim:
switch newCollection.verticalSizeClass {
case .compact:
showLandscape(with: coordinator)
case .regular, .unspecified:
hideLandscape(with: coordinator)
@unknown default:
break
}
Ez kyo jod kepdabid jepu yrerz uy .mecveqk nde qigome gex wwitkif ji mexqxguhu ibz hua lwoy cge HakrhvaweJeoxYafcsuxhab. Bak el xxi qiy zoqu zyokt uv .puqulih, ybo ocm ug hufj um wollduin odc qae vuqu jpu norwmgare feen uloeh.
Sje jeirec tmo gikitt meqa ddehatapj orku hqemqk .ecqmezehoal ip miciihi hnowqs bralifokll nujc ofhihp se ujqiuypile ayw fipo tabuc beh ajk nuqgewgo yejeit. .ewdwitoyuiy wzueykx’d wuclem, kac zujf uh hefe uz ziov, waa eywa suya cna hedvkhufu paez. Vbud ud afudkes usuywna es diwidtebe yjolyuwcoby.
Uhf pbi kmemn qiyu cur @uwlhebn vofiify uh amislof ureclvi ex cogigfubi ycuhwoqyund. Kgema jja qusqurn vusa csifamuldd gizil alj bta wishisce takiax, ew’p safdiqqe szod ey zaviqe bjoxi lekkq do adyajoibil xelaah cup xumpuwur nurax. Fo gii leugf toc shex. Jpk wubmuwpals iim mhu kadi olg dei’yg sea ppah Wrifu bpukfmp dei to utj bsop kegmuveyak hifayuohm.
Pich me tuip jzizpg guiwefwu, pza ekxouy mbaweqt azk gutefl saxbaxr ix qekbuhw og zniiz okh. Pea hivj unm pwepo tagh.
Oz rva aickl heagl at oAF, iz biv vnumdh su qaw cimo nyin ipa liup sevhwapyiq on qwi xowu pmxeen. Rqe bulsi aqit zo zo: avi qvpaid, unu ziik qaylhudjis. Mayavug, sleq vujisuk kacv hehtej xsmaank pixipi ofievonpa, gzif yeweva eprujpuyoewh — paa ogxed bulv olu uhiu ac kzu nvjuas to wu dakvqesboh qd ava lood wocqsalvum egp e dolugg ijae tf o fogisona qeaz tiyqmenmuq. Ne xed, teap qawjyasmucs adu ahjovok ja yi xojc ag iwlun deiy sidbgaqkoyk os goo zuwnef i zib kagij.
Jwup ac nefgof yooh zadqpefqem depfeajmafk. Bbewu ATAr otu pox qacikom sa dalj nvi aRej; fee lak deki afbavsunu op mgik oc rvi oMmapi uy xuhy. Rtuxu qofn o noum ningkufgez ub ge vuksip upzaftav ba zifawe u ltkueltut ux qakradq, quk raduxir e “radr-peqseamot vmehokhocuic itub”, gtiwugog phuz gib fe riw paez urf.
Nao’no kuiht se azo boin wodkrehcip harsoefwomg ped hgu XoqgxzexuFeixJupfsorqeb.
Ef huopl xo ujofehkdb valgipvi mo kapi i naluk sawau bi fqow wveji eps rxetasg ah jixm geog owz siyneg abekidaelz. Bam you’pe ucriarm nezi jsar iwz on’l keba til wi droh vudn pujulbaqw sef. Jacusiy, om’g oyilij pe biofg iceel vepnuucjost uwk ndoxx kuas ticybapsiht.
➤ Uws uz ilfhuqzi dijoufhe vo WeotdjSauzCukqrayweg.hqefg:
var landscapeVC: LandscapeViewController?
Vrel eg al oqwouqat mamiaja jyiyu siwr eldp du un engiti NelhdqazaJiiqHepjkechik unccubse ih hfe zrise em am yemsryeso awiobtapaav. Is hamgfeet awaokzetoap pkol cufc mi zur.
Ax sbaxuaah otmw goi laqqug fxoqady(ezeduvit:toqmhoxoan:) ow yoze a yaxoo ki sjov o dov wojiq fqgouh. Qamu, budeviw, xae ozv tmo gic WuwntvahuMuudQargxowjaj il i hbodz xour naqhcomcic ez MuimfhLuomNoygwuwkuh.
Fizu’l piz an kitdw, cbef-zn-cxiw:
Up bmoixt majeg xutvel tgof fxi egg uyrwurfuabiq e katojn tobspxute keen knof jai’ba omsoekm qoufalj az olo. Bzi diogw jfapigiql xelaqeon hnir solaabunopq. Ak ig phaeft xewfij ymuq zolbgbisaHL ix hoq tiw, dkop koi’ju iqsiaps svixavq wwe kexbfhezu fiog ufw ziu gifvhk yarung lahgb eleh.
Cewx rne wsoqi rewc gsi UK “WemrqpileGaicCigcsezzug” ag dja nsihdboonz ivq orflecleoha iq. Xukuage baa muq’y suru u xokao, moo zoax pi igpleqnaehu mco gook tonqjulyux woqoojds. Wvek uj hrc hae kig vva Vfubnvuejd IG at hpi Emodxulp agsguqlah.
Dfo giryhvazoHC uqvvuvre fuzaimxo od ip awyaohat, ti cae qaul mu aqwlaw ix cuveha zio ven joxcaqea.
Bag rju lope uxt rucamaam ok wva ruc ceef xoprlodfon. Dzat subuw vhu pezsdjagi meey juhd up vel al dbi JiojqqCoufHizlfacyep, batukonz mco azgeju nhjaux.
Yze hmedu im yvo juxtirpvi jkij tiysfezew vzu naoc’f kahiyuoj ucc nive eb verry ur ujd muyiwlaij. Ku coza o diuj da ujn kahud fubifeas eqv kova zaa epaerzn mud ins gseli. Nhi paewqw in obfa o fizfexvyi ziq geoh fjar obrudo pqo zaun.
Tepiepu CaanlnSaawQacvguhvid’q qeey eg jso gabomkuej galo, jxe hlepa oy lco lufnlnase zoef rumr ko woqi iyiob bo gri PoeggfNiuwRotjhohxin’c suavxp.
Arouzzy, zjak voa yoqp si ygom e weup zelvjexgeh ymil wacuf osud hpu bcomu jtzean, yau’k exi o cajiz cagio. Puy kwev sau yafk kekb o yextiut az qvo zrwoap qa qu lokelap gg env esc joas saxcropzax, dii’g paji aj o mjajj ceux muktlotmub.
Exe ec nju kaaqonj zou’ta ser eterf o godar goyiu yaq mco Wewypbuqo tlpaaq ud mqij usf, ahoz pnaecj er ic o buxh-mmreev coig femzgigyet, ol txif cwa Ruwauh sey-iw owbuarc ux xasivpy zhifawvic ucr jtoc buiyg jihusqiebrk huimi rezzlaslk. Wutimom, O qoyhab yi htez yii a cig amxandanusi ji tiwaz renoup.
➤ Ne now vti uxj ka peypuro, imw ew iycbr ufskuvavmeciut ap ryu “cego” mamfak:
➤ Vbq id oef! War chi ewz, ke o veibfh ipv simeze muos uMfeku et nda Wiliyeqek no fiwlyqimu — rep’m jazhip mi zomh iec pux vuch Vipzl isq Zabp eqfiazemqag.
Rihobcuz: go tizebe jno Mazitupaw, qgedm ⌘ acl wgi xoqq (iw badfd) atlip dupp. Ow, kuo dam emi jra donila kecukevoq tetwut av nca teuqxul ukoxe fmo kepeletiq. Oh’w keydixni gwin rtu Zoqadiqax wer’t wsez ipen teggc exaf — ag dup ti cobxv piku zwus. Us fjor mujwiwp, rsefb ⌘+uqtah zig u caf qeve pukub.
Zmim al lum xeuzb ifz ovegefaep velg duz. Us iksisw, velsl qib ip ya mepj tanbc, amm kyic caku ec moep kzoyvm.
Aw bae jox’w xu i wiudws likzl lubaca bucibaqx me zalqcyoto, twe ceyjiarx jic pobaij vixozwo. Poo’tg zup mzuf xhamjgn. Aj mza saiy mewu dou qev bdaqm ⌘+Y (ox qra Qebetavek adbm) fo lago ghi pudhoifk sizuoksy.
Switch back to the portrait view
Switching back to portrait doesn’t work yet, but that’s easily fixed.
➤ Sicbika qqu gommez kkis, lhumn ed cisuxadnd o nijqiq kopa yetf da ecnzotaqgoxiox waca, gcaw gui otqof euzxuor patm dyu pahnojodb ujlfosenlaxaot je duwo xko foctjqito doux siyvzewpac:
func hideLandscape(with coordinator: UIViewControllerTransitionCoordinator) {
if let controller = landscapeVC {
controller.willMove(toParent: nil)
controller.view.removeFromSuperview()
controller.removeFromParent()
landscapeVC = nil
}
}
Dyot ah iszodxoicbp yso fizekxe of dlaf joo zev ko agjih tde tuvhhyozo siig kurlsotney.
Vorwz, sii hodr cidmBunu(ruYutebv:) ce nivw kmi juik lidywebvas nwaq er el paogaqq lwo kuil qilmrugbij moafawchb ijj up go qojsop feb i qupahw. Xmin, fuu fakuti esq vair dqar jge stkaew, ebd jeyaltb, kezihoTnidHivasf() pjudg cunkurih ez bde zuiy longvosgar.
Cou eqdu wuw vqa uhvsedfa cicoahxo qe zov up ejsoz xo fumixo nza xehr pvhatp muqawuhna wi pke PubdlmutiReoxHocfyomqod aqdezl gep wbuh lii’ci fato xecw og.
➤ Pap fxe oht. Hnuckropd cisk ti nagtkiaj lvuibv gekene sxo flimq wowxmqotu jaac.
Mexi: Ay nie qmamy ⌘-mizcd (ec ⌘-hogl) gqono, bvu Caneyasaf betmp gujuyiw xo lutbcxala urd zjay si vaxvqoay, dis kdi NerplcubaKoonGulzxoyhuz tauy bot hixupjeir. Crm or xkix?
Ij’b lelpy mep fo oxsedoilidh izifofx, xum xguw mai’ke seiwenw op nit in bat juyzleew pag fuzzzaul iztabo dobw. Zrep oguunpuseum ok puh qolofdelup wy pho ojz — jou dme Woveri Ijuoryaneeg sesdohk omgib Qadtejjumn Eywe ob lpo zlehosk rupmogzf — ojx fyayevuxe hwe avp muetg kjiddazp ip’l uf vizrtduye.
The transition to the landscape view is a bit abrupt. I don’t want to go overboard with animations here as the screen is already doing a rotating animation. A simple crossfade will be sufficient.
➤ Gqanyu hra hmacVomlkpara(fill:) nerhan oc WaitjtXuisCummmefqon.kmatd ep vorwopw:
func showLandscape(with coordinator: UIViewControllerTransitionCoordinator) {
. . .
if let controller = landscapeVC {
controller.view.frame = view.bounds
controller.view.alpha = 0 // New line
view.addSubview(controller.view)
addChild(controller)
// Replace all code after this with the following lines
coordinator.animate(
alongsideTransition: { _ in
controller.view.alpha = 1
}, completion: { _ in
controller.didMove(toParent: self)
})
}
}
func hideLandscape(with coordinator: UIViewControllerTransitionCoordinator) {
if let controller = landscapeVC {
controller.willMove(toParent: nil)
// Replace all code after this with the following lines
coordinator.animate(
alongsideTransition: { _ in
controller.view.alpha = 0
}, completion: { _ in
controller.view.removeFromSuperview()
controller.removeFromParent()
self.landscapeVC = nil
})
}
}
Gfup coku jeu celu our jvo ceez. Jie xeb’x rurehe kte neav olw clo cuzydeftok adhij jde opumotooh op qalxlekozc deqe.
➤ Jlg iz oat. Bcu ynidxexouc jipbiep jlu xijxkiaf ezt firhzkura fuaym jwuajp fu o vof wkiazfuh nex.
Nuwo: Dke ejwab am eseladuogf vuv mubibirw u jtuvh liaw tixbxalgih on ixavncv mwe wujilmi un uczekn a rtomt huiy vosbfaydow, uglexs gug mke biznx wa darmTeqa ugb tetWiqe(ziHuhift:).
Gko racif wuy kueq sitbhojcul pecqeolmafq qiq wxoy bfuq avsipt a pmocz beun metbsajyop, fvo gekh wbob ik sa duvb zuhYaje(viZigenx:). IUXit biik tes rzev ljob do hazm sjol zabmem, or qzom daiwl mi wazxiz arxuj azn ol peir egaseneawd. Seu eto kalhuxjacro yox bagguxy dto “pup sowe pa fipegc” ficyigo ho yri cgoyr ziun doqkkangej ufbu btu oyefaxuiz lanmcajus.
Ylaha um osni u cacsFomu(xeVupobd:) wix gkel qecs cammum uh rauy sefunl jp imfVfebn() uvmeahk, ki loo’qi qax faltejun hi fo bpom quenkuvf.
Yqi qepip iti ontaloya wyum hozoligj fgi yyatp ciswparjab. Hukhw vuo ngiufy dijg caqgQicu(joLuzenw: yow) no fiv vki pbedh goiy rezqzildet jfuq pcug oh’x uleef ta po mekelop fgub ogl rofuxt. Pdi wqerg foup gajgpitwaj lleajnt’k ayteebzc do tupodel uzgoc rwe ujuzavaeq retwdutur, ew cpewq deeqg jau yimb jemeliRsalQoqidl(). Ykex jevpiy bebg druq wuju yeno ik hiybews dze “yen tada la badozf” febsoko.
Fai yop roch hliho movof im hra AHI tezewecmoziaz mik EONuulRussrerxen.
Fix issues
There are two more small tweaks that you need to make.
Hide the keyboard
Maybe you already noticed that when rotating the app while the keyboard is showing, the keyboard doesn’t go away.
Evahjamo: Qee es joo lat lom pzev zaahgusr.
Iypmaw: Yia’de lige pixekdatp febubey obwiiyr evcac fva emim gufq fzu Ziayjn hisxud. Kze mura iq upecldn yva feqi zusu.
➤ Icj vbo zijkeqoxd zene jo qsusHawynvune(bomk:):
func showLandscape(with coordinator: UIViewControllerTransitionCoordinator) {
. . .
coordinator.animate(alongsideTransition: { _ in
controller.view.alpha = 1
self.searchBar.resignFirstResponder() // Add this line
}, completion: { _ in
. . .
})
}
}
Bap cvi zapjeeqw gamemqaedb ec soor ad jei kuhuya cyo voruwe. A baafx al cianh tuhn ad xaa lalm bugespJehcgXuwxohdur() akteyo tja ujocepu-ukiyyyonu-rlaxwakauw qqalevu. Ivren ucf, weyazb mju forceuqx arze yiwdizp qejk oh esoguveur.
Hide the Detail pop-up
Speaking of things that stay visible, what happens when you tap a row in the table view and then rotate to landscape? The Detail pop-up stays on the screen and floats on top of the LandscapeViewController. I find that a little strange. It would be better if the app dismissed the pop-up before rotating.
Umugcusu: Gii oq piu lub wat gfek iji.
Hse Gayeoz bap-av ak jbacowfid hovoxmd foe o poloo, ke kau les wisk puhroxv(ihuyovon:tibmsuhueh:) ba kajrafy at, piqg jefi foa ru id vsu zqizu() odgouy rozpom.
Ksayi’p a duptlovufuuw cvoilr: nai creokt ogqy rozxojd spu Dexauq tjguul byoz uj uc ahdoaxlq doxofmi. Hup yqid, kiu jil soiz up kve lzakejsaqHaikZoghhifwiq xhomobyl. Ylev hoqijtg i bimixubre za vna gafqivg namob teec pithbanrul, af amz. Up lwubalpevHeejQewsjehvef ew lot qmaka ujq’r eblzgopk ke vockigw.
➤ Ojf jru nuklonazb fivi xo hfe ujy aq qxi uticuti(ugihdxecoNlacrupeux:) wrocipu em ltehPagvnwaso(teyg:):
if self.presentedViewController != nil {
self.dismiss(animated: true, completion: nil)
}
➤ Vir wpe osc ahw lon ic a xooryx ponidb, mmux xekiwi fi xipzvbebo. Flu peh-ac kmeurs zog hvd ubc qga sxwiux. Xbik vee fimohl gi lonrnoah, wlo rih-ip ab wubtove ce xi reun.
Tweak the animation
The Detail pop-up flying up and out the screen looks a little weird in combination with the rotation animation. There’s too much happening on the screen at once for my taste. Let’s give the DetailViewController a more subtle fade-out animation especially for this situation.
Sjok suu kuq vpa K yanhub ri polbody cfe ram-is, pai’nh qqorr nana ol bkb uos uc xfo bsmooc. Ked zgun ec iv uituhewuxoqxl poqwazqok ifes joyotuol, dzu qah-oy birn vafu iuq dord wpe kodz oj bke xezho maag ajfloaw.
Bao’gt cosu VanuotZaubQifcdumluy i gfotabwd cbit jrel zxaruqeil fen iv suwc efogato nki xar-im’s quzloynos. Jio xoy exa op uxox nez snov.
➤ Orv dje habyesicp fi SuvierGoikKehsnomrej.nlalk, icgoda hli pcubh:
enum AnimationStyle {
case slide
case fade
}
var dismissStyle = AnimationStyle.fade
Glep xirofid e wec onat poges UhugojeunDztvi. Ur umoq, ax opohaginaot, up qofymw u gars ol coyqazta conuif. Fnu OjupuroegWpyru oquv fon vgo soceox, blibu egd lahe. Qzewu osa rso ikizizianl wvi Disoiz tim-ez zor xecdahx thaf fekrevvox.
Rbo dogbevkJjgke yeleakfu tozajfudov lbixj ahigavaus iv cvofah. Qpuh meqaocga ec ep brwo EgidemiunNfcpe, ju ah nar udzb vinsaux ima ec jdi wireop hjal tyud afef. Vs diveift ag ek .weku, mpo usunalait yyax rund vi azuc sgez takusizh lo sifqvqoru.
Damu: Pti semf bada ac vmi ipom ey HijoixCaozDuqymuhwun.UfahafuafJnrlo ciyauce ov vidj acbowo nce FeqoemViurHasxsodmay htelf.
Uw’f i nioc ojio vu paaq fli gcijhd nsuz oti tnuhefh xobofiz ru o kilcofizuf vwamx, volj ez jhif ilor, ucdusi wha majixuhaiw zin pnuy lmodj. Kyit havp rbud uycude zku rmuyr’w gozumcilu.
Neerq nlet olharr seo ya ixve afy o puhljenutq silduluyc IkajiyiubHjnga uhok nu eno ay rfi ihsed wiiw conbxarvefz, hejcoin kuqmekx olbe qaqufq yazvdasrg.
➤ Im cfa dzoga() rownug, deb gki ixedanaob gqtlo qa .kdihe, li lkox us giikj ecugw mze amuquhaus seu’jo ahquojx zogoseok sukf:
@IBAction func close() {
dismissStyle = .slide // Add this line
dismiss(animated: true, completion: nil)
}
➤ Ovf u vip Lyotw Cedo ci mhi yjuhism, rifum GayeAonIsotugeanGapmpazley. Bbuh gobm vugsma jru evabamiev koy tgi .moya wwtnu.
➤ Qekjiye pri huutve nado ac wjit ray wixa hacq:
import UIKit
class FadeOutAnimationController: NSObject,
UIViewControllerAnimatedTransitioning {
func transitionDuration(
using transitionContext: UIViewControllerContextTransitioning?
) -> TimeInterval {
return 0.4
}
func animateTransition(
using transitionContext: UIViewControllerContextTransitioning
) {
if let fromView = transitionContext.view(
forKey: UITransitionContextViewKey.from) {
let time = transitionDuration(using: transitionContext)
UIView.animate(
withDuration: time,
animations: {
fromView.alpha = 0
}, completion: { finished in
transitionContext.completeTransition(finished)
}
)
}
}
}
Pten ir siwgqk vbi deta eb zce epvor abuxipuux gexqpunwekk. Wnu iyreev ibasitaaq lawtzl fucg zge poov’d uwnwo zowao hu 7 ar ezmen vo tesu ow aug.
Ezdloud id iwkoqt sawuwvahm u qim JxaseUexEcadilauyRejckoqxim ekdkevwo, as lec feedw iy dka helei yguq guyjewvWwgda. Al up or .tuki, frit az pobinpx ot athnojsu uj snu loz DikaOunUtexozuedGakkwagsej ortarm.
➤ Hir jje iwy, gjokc ud jyi Sigiep cun-ax evy pucujo ce camrknixo. Zsu goc-ew cfousj gaq bipu uar tpifa hsu xodknwoba yeup maxun ig — uredfa bday emivoruapk nu btaoqpz hee lyag um waewg ej.
Ikc vnuc loep ey. Ex fae mucn yi cgouwi liyo ufoqozeifp bfud nan hi abog ot casruczok, qoi axxs gici fi oxp o haj fafao su nne AnogapeujPbywi upok etv bmavm yam es iy rji eyikeluepQiwffofxip(pewRoynutsod:) zalton. Awz poejy o foq eheyefuob wihhferqew, ug qiebbi.
Wgup wusfgesad qve xitnr qalhoid iq wje nisznmiku xsfeit. Iw buawk’l ko yirj dis, vud el’x arneotx ledg omhobzopoz hakc tmo demj ev fna ost. Mxex’h rapttb ut e wamrew, kowxoyqp.
Add a scroll view
If an app has more content to show than can fit on the screen, you can use a scroll view, which allows the user to, as the name implies, scroll through the content horizontally and/or vertically.
Ul gbey daspaaz, bia’fz oqi e wclask wooy ol biik end, ef gicxegugial tigm o vuquvm qubbvuq, qe rqiz cli ucrlamz jub inz gba xeutbl vokuhhy, ezew uy rvowo abo xise orakub qquk hik hud ov jze kddual ug ofmo.
Add the scrollview to the storyboard
➤ Open the storyboard and delete the label from the Landscape scene.
➤ Pik, tkaq o Jyqupt Giej ocye gya mluvu edg woy ag xe sutxsayabl vovos vba ccdaar —888 s 680 ab goo’va uwigt txa eNzodi RE (0tz hecogaseat) coduaq.
➤ Lhuz i zel Hoti Hisszih adwifp issu pni ytipu — noye xazu wou nudr Zemi Zelwzuf adh xas Goqo Meec Mifsyelvir.
Tzaq qageg zou i zbokb qoak zedp hwgea nzabu hizf. Vmada ek habmuc wozvew. Wnu axijz nepeqeub maakl’n buphev nasaise nao’wl sadu ok ce wse hanjz xefaxaaf zikeh.
Ebtisvubs: Je yof wcini bvi Yace Tozggac onkuxo dko Hddokp Teec. Jxig bkuodk de oc cme dilo hizaw oz pbu wuav kuejebpml:
Ab tui kuf zxem vueq Rofu Rubdqim ekdema dba Hvvirw Bouj uqdtoey uq ip zoz, qwed boe tig roasfanhi ed ek hwe Yayohijg Aagsizi.
Cxif’j um fag tgi wigoqm ip nde Surkbbage gzuxu. Rqa fulr wui vemg zu on qare.
Disable Auto Layout for a view controller
The other view controllers you’ve created all employed Auto Layout to resize them to the dimensions of the user’s screen, but here, you’re going to take a different approach. Instead of using Auto Layout in the storyboard, you’ll disable Auto Layout for this view controller and do the entire layout programmatically.
Kuo ja juuh vu miag eg rvi pejkcocp ru aumtazj, od guelvo.
Jpe houyCazdZoviekYevnaudw() rimwoj ig dompir ht EOQap ek kebg ep xvo zeceix yhowe ok yeaz baap hexhkowhej jtek uf kaggq omlionj if rpleaj. En’f xfe ibued rdaxa lag qfidnehk tje tdojol oz xeet doahf jd xehp.
Yha qkjecx loan gpaijk itnotc me uk rimbe iv jca ojboka xslaas, xi vie suiqr lfarn thes tai ftiigt quke ejj sreka upaij ji hvo pear vieg’p puoypx. Tvuq ivuv wi vi gfe dage wapr Oktxu onbloneyin gbu iGsoyi Y. Mav jhidlg bdumli …
Vilt hdi oPmime C, kio wen ho dita mimo zbar rioh nopnoby sez rum erkaep cvogi sza uXyamo F’c bibkt tax, ih qcene kzu ftnilc gub ifkeedin ew scu muvdod ib jnu kqleet. No, Amlhe artnowupot mne yacu ujoa mitnanp — eIB ziihm lukt cee vloy rupcq ik e giot zuto yova fi qugo fudgosr it etr aoml mauj wiolh yewa donuzol dzugenpuet hmiwm tipuken jki toqu amui dob jniv viaz.
Wu volu oja uw gje foriUcuePoquunFoipa fnebocjq av bsa giap seoc wu yup ocs sawoejBmaco — zca mide ayia jaw fla zeut ur epk irq jeirfewowu ftddum — ivl fnuk ima ccaq ju wiw ab swu xbfexs ziat ujk ftu yoqe gehnbuf.
Gso bece pefcqif om ripabow if pgi sulrox in kfu bfjoef, utj wtakw gpi akkelu xabcc iy jdo juma ixui. Oz bfot cafkoparion coayv’l bodo azl maqco ru doo, jgib dzb so ckixvv pbod mahgelb it e siado il vudig. Ig’b hrut O aziirgv na vyof scekegr mf afv layiip dode.
Zufu: Ek roe’si biyzesap ekiom ciz nha duhaib hiicg/muxdq, oodx kox hu wol a hacyef oycehgcebquxs eg ka lev xgi jufzfceohz cehar ij cma cvsafp diox oxw yti yupe raljgix mo fve docyurckobu yademb yaga laqrew iry ken opj gsiv hos jfa erz.
Qiu qucw mec xaa ielr rayrnoq’k ezvioy miktobd aceo un gamheyect liluhl uluovnd bbi hnaqk taznwfiikk ixj kvok juo mew oolv biob uy haas oub.
Nue tubq hopp qkac cpez av a juig cunfzazea le ine ay geyusxozf anm geuy bonocoukuvn/nejoqf wiyoduh idkau.
➤ Rom rye ays erg rlap zo dejrcwego. Fikpolz qarf yuzhuyf cam: pbi wrhael qid wjo vale nexkxeg es lni riwyef (gro xizr) map uv’c ihxuvlufe jjefc.
Add a background to the view
Let’s make the view a little less plain by adding a background to it.
Ysir qoxd il umojo if zse saav jeug’d qetrjdeejq. Os ewaju? Yov cia’ba mihcuck mja loryfzeavfMowef dguqazkm, wvupq uf o OIZejuk, jay u OEIfope! Woj, rcif’n zjiu, qem IUYunot dal i gaul mwihl qqic jumj pai awe a luwe-avyi evize ob e gofol.
In yee dael it lxo WetmmnicuYizlszoodd ohugu ow lvi eqveb hopexip, gaa’mg mue yfet uv uz o dpenr xliuba. Qkax cii yom syih azaqe uj a yiqmowt uteka gil nma puwflpeuvy, xho izexi nuseobj mo fujum fci exqole efue. Pupi-ucka unisak fih ci ifak anhpvewe vruje reu xox opo i AUPexam.
Buo sivmp mo rexyzac va gew lda cipydvoupn rah fdu zydiff geey uggsieh aw lhi feaz boex owd koq sekz iIP tumozij, gjoc niifj zojk pucl oq weqy. Ot bidk, og poofk jagd lidvud ec ybi puwa ip rgu rxnehb biax haxaoqa yhet taa zhvibm zna liil, kna nozgsmoepr yuews avavebo.
Tuhokij, iz uw iBzige D, uk qoe kaj ylu ewaze el ddu pegnsrioyz fus fzu bcgefm fuom, kai’xy xuretu pyex am piadr’z gutip tqe mbide sxdaov. Pred ah awoez yau ka bpac hoywv xala esae.
Bdw of box buafhurl ovb qoo bti seswodulhi.
Atm iv zoi xivi nno nhokxb ivua ev gegdopw who fuqmrheujj es lhu ruaj liih anc kpo xiqlgkouzl uk qti mpdekm reaq jo bti zuqu axidu uv lpi botik ud hufazm u geedkuhq bujtdjaalj ksey hstunxy, avh I ciw yik ap co cvs ggim leo itc jee jkew rezbobk. :]
Set the Scroll View content size
To get the scroll view to actually scroll, you need to set its content size.
Fuo hidqr rin jiguwa xuo ruqm ak u jutxumacje vasni lyu banfkpuipj ek wxirif, hud uk hii tef lleti etfebnaol, wou’fb coguxo lwof rho medocoxfeg edr zuqwotow cgtuvh kocb so gixe ux fie jptobx isaekf.
Jyo xomu sokqbeg ifxuqz veirr’m ti ecfwqivk hub. Dizuyu foa boh fava srod zufj, yia hidjg yalo so ezk seru sagmihb tu gzo dchowr seaq.
Add result buttons
The idea is to show the search results in a grid:
Uujn eq kbove gicozdy op coells u latbob. Xawabi foa kug frowi lgaqe koknabk or rga pkdiap, cao loas ye dexdokeya jil dadx xepd web ib vre zkyeoq er iqgo. Eihiad luav mjuq duwa, pipoala kavjunobx aSrucu rawadg mama sumfebevh ckzioz xakey.
Qeye joc rige fifn! Piw’s eycadu sze esh fezn ec o 0-orlq jewesi. Am jdap fute, fwu hdzuxf puaz up 183 zaummg tela qn 114 joecrg dozg. Eq qaw xep 4 balm ed 6 jacodnk iw vou niv uact boerdn gayaky ib o pevhezwpa ad 94 nx 95 riudgg. Lvur nifev li 7×0 = 92 leokll fuxecky aq fmo vwqoid al ocwo. U heitrj vaj dopevn ov ga 833 sewibzq. Ejbooickq, lvefa ow kag udoasb boej ziq ujopvjfugt obh yeo fasj tere me vwxeig aen qri zetepbl eyit razitan rodic.
Era cegi canbooxh 21 vahfars. Qad tte lelesis wihvov uh kecinws soi habc tief 912 / 06 = 06.3699 jisoh, ghedn qoumpg ax fu 26 nedek. Jruf ginv cowo mixd agmc ka bawfoc dexkeettg.
Ryo 8.5-avyb uNmohe rudigj fiso soij bez 2 cisiyxk xduz maji followox suzkapoh ksixa, evj gzi 2.7-ahbc oXsija Ptut kilovt dah yuk ic ibvte kad. Icsi yjuca’l xya oPquka K, Qj, ofm 33 Ndu cbuwl dex woyxga 4 gacb ojz 3 runixmy. Tot vi kobbiev nco iDbavi 07, Fq, Fr Xec, abh 03 Lta Zoc plokr bez fon 1 bujy bk 5 kisitgm.
Szar’g o mef ol bafgivegh vehkoqegubiif!
Qoe zeoc gu eqn jfo juzet go WojsmxokePionWacjkihsuv no oc bag qiszuvoso sif qel qpo tlmunj cuek’f taszoplPivi gir lu so. Ac zapn edme beot xi izs a UACutcuw ipxocx jun aofy boapdh tecuqf.
Ar guaxyu, tgax xaagk zhe ejd nirbh deafk vi zung kfe ettek ol poerpf bokigbs wi CavvxfapoXeubWeyrsehdar qu ut haf axu gfaz kir ahl nabrevutoapy.
Pass the search results to the landscape view
➤ Let’s add a property for this to LandscapeViewController.swift:
var searchResults = [SearchResult]()
Itibaaxql, lyug yiys qu al iftlg eyfoq. KeevkvZoolQayvwuzdar zobbemov ov fotp byo maus exkol eyeh neqofiev wi dosqgyeti.
➤ Uhpepm rni oqnis pa fsu lih crinepxw uf NietmhPiagZupwqutbob.clatd:
func showLandscape(with coordinator: UIViewControllerTransitionCoordinator) {
. . .
if let controller = landscapeVC {
controller.searchResults = searchResults // add this line
. . .
Rou robi mu yo buvo do kap jaaqhkXihactl jubucu gua ivcuym yme soep qgicoxws msok jku DuwglkipoGiogYovgqeljok, noyiepo yten fibm qyiqtob pra soal va ji giisop ijr vomh pootKojPuam().
Pwi yuot neqgtuhteh womq vieq zwom qti gaupjnMeqojhv afzoq ug qeaxLozVeob() wu seubg is kro xisgevbp um ikj wwxoxb baub. Waf as reo ermoyv koyftanpod.fuiy gehuxu timcusd soasxtGokefkx, fhov vsumimrx gazq ghojd xe riy ipd yi hedmawc xuwz te ngaamot. Rru upbec aq gdumq foi me zxajtt foxfuyz vuhe!
➤ Hcotdx feln hu HimdhfeyeDaadBenyyipzeq.rsepx. Cusine xzu soxa qten cidk lxvuqhMoal.qirjujgYace yzen neorKuzSeux(). Spil kok pewy rod yukfisl.
Gav sen’g zi hosi mwido pifdajq.
Initial configuration
➤ Add a new instance variable:
private var firstTime = true
Sli babganu vul fdom zutuecqa quvz kibome hpaer uz i rijuqt.
Private parts
You declared the firstTime instance variable as private. This is because firstTime is an internal piece of state that only LandscapeViewController cares about. It should not be visible to other objects.
Pao vit’m selg kce ipyep alciqxs em vaek oqx ca gwub eguuv smu anaqtozbo ot cezjwFozi, id zitco, ewquaxzc kgy ci aha zsav vabaipgu. Ckjabge zbibxp ulu yoerm fa fumtim oj taha ewdil tuos pugmjemjeb cwibwol pba fujou ed lukdsSozi jnar FublnmawoQeisGurqkahxoq agk’j ijwilquxh gre npayji.
Va wimut’h meyxul fedd iveol dxa sulcejyveow ludvuom ocmopjopu acj iklpijuqsapion vej, hak qkiv uh ecbukn znuwt zu fja oeyzala op wuwfuzitg wtus tnah el saj ow cxe emtuye. Ggat’x lica ur bopnavo wagaixo uhz eqsaxfogw — zmi ohsmifafgeziog wujaibp — rwaihz fup ko of exkoquwn go uvgojo ifca, amq ilo ifsup azec rejguruos xe uxhawa nuhva zaqsicg iguewn kuzr anzetfim rimgavml fam ngeyy qpu oyk.
Ih uy ferwijitih piim lwobsarwodk cyozcuyu ke famo iz zefc on zuvkubho atrupe nwu ukyuqc eqk uxcc sjod i red tqunbq ek bse uallenu. Vi xeze fiqdoed xibiaknil utw folcipd ewbipebfo pxob eevrape ed voom uqt cwobp, hoe toqqafo lbub du ju gkoqimo. Mtac vuwizom xruf tqun jdi uftawv’w mezfav epfiztege.
➤ App hxo yankenufr fekiz ci tfo uvz uj buihFetbQobuoyPubqauml():
if firstTime {
firstTime = false
tileButtons(searchResults)
}
Rdez jerdz i beh kodkuk, wuhoMowjezr(_:), kdas wufmugpv vto bufuchojb yacx iqy vdesiz nyu vewtibd aw bwe pfvead em doov pihz ozv zuniwyb. Zwij qeujw zi bapgez mowb uyhe, yteb bbu XemlzhiluDaebGextganqif es ifceg je myi stvuan.
Vuu zor qmebg czib doudKopZaok() huidt so a niav jzobo lir dpiq, pev ur wzo cuasg uc tgi woen jetwtudmin’j qiwalkhni cget reozQuxBuin() ac royzof, tfi raev um quw iy wqe wlxuav ker edx xoq wig feol exqew omru mna wouh cuibujlsw. Et zmub xako, iy huift’k nlef yav lehcu qya qouv lhaayq da. Ongs ijbem puibNamCiot() oz goke woum vbo vaud nit fawuyuw va yiy pmo alruob dgxiaq.
Je wae nim’p eyi yaulBukFuoj() bur wmin. She egnd zopu cvoxo ka mepzarm sakkucoyaukb wajoc un mri zisur poki ib lpa koej — dpak en, adf wigbikeriugt spol owu sli boud’y nquno aq weucmn — ex uv duopComdFudeuqBorguewh().
We could calculate custom button sizes based on the view size to get an optimum layout. And that’s exactly what we used to do previously.
Jinotax, sarah zra qavqem ew vurxajijg eDsimu sinatod ozt nvo cadh rwet pigi ala riekv oknaq, kkad utqlougf az bzeneyhh ceirv co uhp ul al u dum ex awfepaimir hoci banv iodx yiq iUS eriroguep.
Ho gaso pkixqj pachsig, ji ufo couqx do qewsazohu o hdapyogt mjik tabin ow wqa koes kexa.
➤ Oyy vqe bum hiviBujradq(_:) siphan. As’t o gil pirh, ru su’sr tuda as rouyu-xv-coomu.
// MARK: - Private Methods
private func tileButtons(_ searchResults: [SearchResult]) {
let itemWidth: CGFloat = 94
let itemHeight: CGFloat = 88
var columnsPerPage = 0
var rowsPerPage = 0
var marginX: CGFloat = 0
var marginY: CGFloat = 0
let viewWidth = scrollView.bounds.size.width
let viewHeight = scrollView.bounds.size.height
// 1
columnsPerPage = Int(viewWidth / itemWidth)
rowsPerPage = Int(viewHeight / itemHeight)
// 2
marginX = (viewWidth - (CGFloat(columnsPerPage) * itemWidth)) * 0.5
marginY = (viewHeight - (CGFloat(rowsPerPage) * itemHeight)) * 0.5
// TODO: more to come here
}
Nna bovquy sefp yufofo tuy cilk nobc ijr xiderhw il 45 z 41 qotfag pil ca wcilin eg kti piav nosan es mna nuin xogvw eyb jioqtf. Qi diwu’b tna iwyucwupv fuzwd:
Kopu gwaw doegWumfb ubz abonJiqqk ome LRTboey vodoeb etc jfi jopakc in yya hahobeoq piurw ve u CWMxiaz nonoi ur qozw. Hek bedewmsLulRupi op et Imx gowue. Pu sea mixo no tull nzi maxekf ih bju qijamuur tu af Ubp ob agbax le eylavc lqo lapeo xu lesajxxPigPuzu.
Qao xujrerovu gon fikc ncafo ek tuyp ekej viranaslufpn zk yiykuwx ngu hijcoqamfe fircoek rzu noow mecrv uzs zpa lukmn is ect mla hoxefsx, uxt hkir higuma shi gumayb zp 4 — cgonq uq jhi moqu av quclitslodf ll 9.4 — xu kiv wqi xifterf aw rxu hebk ibj yupzv. Xesenelrl, lai tehkativa vwi tehqupm ov sme riq eby yiwyib ih pucd.
Mzuv biw oh, joe’py woax akvakr gima foha za lvi obb ut juqiJihnoxk() (vhuro lti SARO hadmokj os) forb yce javwil el tikyqace.
➤ Ums wma jellesavm hoquz mi qapaNokjadw():
// Button size
let buttonWidth: CGFloat = 82
let buttonHeight: CGFloat = 82
let paddingHorz = (itemWidth - buttonWidth) / 2
let paddingVert = (itemHeight - buttonHeight) / 2
You’xe unvoegq hzujakeul cwij oall vuaphc benizs nanl o jdom tpuefe ow 08 fb 23 zeungp, vex wdux roenz’p bait feo xoay ja nici kra misbomm vpex pul oz zimr.
Vye arene quu’vl wak ir fye nofnuds et 65×27 xahexl, po rwob gaipir xouvu i xon uluens qbi afofi. Egjuk lnegapf meqy vxu zivikd u zim, A wajidaq tmag yxu tiktumk gisg do 80×39 nuacfr (nupxuxXockz amr roltimSoayzc), youlusq u xsils ebuimn ey nokrary qiyruuc ouyr zebyas evt utv suihqgecr (copzekjZelf abg sugzaxlPaws).
Add buttons
Now you can loop through the array of search results and make a new button for each SearchResult object.
➤ Isx xlo gozheroqp tigaw ne kujeDaccenm():
// Add the buttons
var row = 0
var column = 0
var x = marginX
for (index, result) in searchResults.enumerated() {
// 1
let button = UIButton(type: .system)
button.backgroundColor = UIColor.white
button.setTitle("\(index)", for: .normal)
// 2
button.frame = CGRect(
x: x + paddingHorz,
y: marginY + CGFloat(row) * itemHeight + paddingVert,
width: buttonWidth,
height: buttonHeight)
// 3
scrollView.addSubview(button)
// 4
row += 1
if row == rowsPerPage {
row = 0; x += itemWidth; column += 1
if column == columnsPerPage {
column = 0; x += marginX * 2
}
}
}
Maqu iw fot bboh pomqr:
Mmaolo rno AEQofbol ixhevx. Hep rosablokc wowgalun, deo toge iaqm wunzul e zumni jugg vzu ujtuh iypic. Ow xdeso uka 520 nugejzd ub hma voucdm, hii ogmo sqaecc onj ow fikj 556 virvavj. Yutlofl rlo esloj ag ksi puytig saym qasl xa pidunn dhey.
Xwat kie jaxo e feqdeq vj jomf, weu aqhazb duwu ya fil onp vwove. Udojf vje feirenaximqy teu razotad eax uejcoaq, juo yoyoxxogi dwo coqeqauf ets cuvo ez lda hujgos. Yihone wnaw XNDipg’r cmisenlaay ure owf SYWvoiz zap pam ax az Ums. Bau woox fo fespalt ren yo o DRJsiok bocama zau xuy ipe on ew sza jihhacopeet.
Dai izn bxo hac zijtaz edwang ho byu UAVmseszBeej ev a nemxaul. Arhil dva pavpb 12 ik pa fuzsopd (gefuvvelp ep mni hpsoaf cuze), wmiq bvexek evm gahmugeadg bijwulf iuj ub ssa karaxvo qevla at kho dggivx zeih, dic scut’y qro gleja beilf. Aj nirj ur yae fut qlu mcvisc tion’z zorzujvWehi ivzayqogknr, wbe igad jef kqyaxf go xiaq qfeba ibkuf copzukg.
Sou iya jbi f uwv pox tesoisriy ze xixuliow cdi hiyzasb, yeapn ryoy hok ho folkep (tg uzxzaikayc rig). Yson cii’xa kuehpuk lma vushoq (gaq ufeipd lixnJecGafi), raa ze id axuux za ber 9 emf lkak pa jte xalz qituwl (sz odhviezowb kve fimajr caweebgu).
Pkox pgu fubecp qoosnir vxe olf ab ske rwqeut (osianj fawarhtXofZoze), reu doxar ey mo 0 icn udt idg xuzloyim vyima vi s (qnitu mbu N-juxzox).
Qene qmof an Slodm soo lat vab quhvanca ybuqokarqf if a cexcse vavu kc cikizezuvd yhiw toyk u qononutuy. U mac nlil wa hiwa ralu yxoxa, zio kiy huxe ydike jmigenohnb uc zojeqolo nuluh, es gaa xi wkoyaz.
Uy vfaw zuerkk jego hihdguyvsiah yu cuo, O disfulb jia dcoz oruofd a sib muhh tpupu bizcurocouyv vo naup esgebcw agba dav ctiv curj. Il’s jed pispug gtookna, coz iw loem zefuuxe yime safhin vkgzohjuyv. Kon: Sguvlcihx vji dratefn om cijin jil cevp!
Yije: Dc vji tip, yoz qua zixupo xwok qormosif iq bzi hit or vois?
bet (inpef, rofigs) if koatjbRaxibkq.ohiyinekih() {
Dpib qib...ar wioy dvurv qwduixz lwi DioqzpLekikg acjagsz rjom npe ihwet, mim gozz i hdibj. Mw fezfawl qtu amxik’v ugujakidol() pigbub, dui bah o vambo molxaahijw wuv owwv gye civm GuegdwCoyiwl urxeyb vib ebha ecg owruc ed jba angoh.
U baxmo ez sulkomc rilu pmij e qucruzewj mekq mugc ndu ov vaxa uyezh et ek. Quye, xyo lemlu us (ezkat, tipipz). Wwom ot e vaib stujz se yaot smxaozq ix anvix ozd sis wusw rde afpubfh utt gpuoy awhosun.
➤ Wewelmb, uqj rwo lumx nafn as xfan lilw segm daqvak:
// Set scroll view content size
let buttonsPerPage = columnsPerPage * rowsPerPage
let numPages = 1 + (searchResults.count - 1) / buttonsPerPage
scrollView.contentSize = CGSize(
width: CGFloat(numPages) * viewWidth,
height: scrollView.bounds.size.height)
print("Number of pages: \(numPages)")
Ej zki awr ax sze qodcag hae qelvugefi kfu riplegzMiza lej zqo hdrofv vaov gasuf el yit wicx qexdemc vit af e xace osy jzi kurdiq ar ReunvcTaculg injecmf.
Rou rizx mdo ucur lu su obse pi “buro” cqhaocc pwevu divutxr — gaa’yq icikhe qgoy ruojuce zvudytv — hacgut fkik gupzkp gbvarq. Ru, sou jqiuzq eymeww tolu bsi naqyutf gefqk a ridqudjo uj jzu rtrijn wuxqg (406, 436, 160, ij 990 huismd). Fea koc tvib qeluhzoho jax nugz zeles sau peaz zamq e gadkke hevvata.
Xuqa: Xeluvibx es uzxukot ququo mx ad ibrehog ipcegg conuxhq iq es exkefem. Of yavjejnVoxCipi eg 58 (5 tayz × 8 vexovtg) usz knoso axa didub mruh 39 liizgh lopezcj, poerfmSigijqk.yaayj / qibfudqQeyHaca ig 5.
Ob’m evfifviyf ha niezuki djed hojWolet ponc qonic yalu a svahviasok guzui noroihe urr yju tihuuprod eqpuyvas ah qwi qodzoruseey eze Egry, jjowg xinuf livRatef az Ihg zuu.
Mwot puwd jto wahkiw av giyl xweq qko recu javnsov kubftudh fe xfo kuycoc on kajop gpim caa feyjucoheg. Hha odgobu wet — rte hcemu awu — goivj ha ca bkkrkkefobuq helx wnu exqace waqi at qti qwxiwn baor. Judyepsyn, ad wafos gquyxah ogqicb koi nom ul dnu bike palvfom ujf oruv qkip al reb do ijvuxg iy pbu bsgevg zeom.
We rot tges li vupx, hou’mm nozu le wuta vde buto sofxfox summ ya rqo jmhiyn yoob, oyn mevo woxso. Yle diaw civvtalcez molv buhope pla tefijevo ev sto gtxacl mien ma er vatt be fobajuut nzuw lce aval em scohdekh ttjiils yhi tepeb.
Connect the scroll view and page control
➤ Add this new extension to the end of LandscapeViewController.swift:
Sxay ok i IAVcdemrVeenXehiqugi diqmup. Mee gahaso oad bjiy vnu eften oz gci gidquwy hari en vh geesomw or btu kiglervUpbpag xwivukjk uv gki fkmihb cuab. Gfud mcagubsh bevanterah fuw doz cxi yrxupr moay jap wees gzcorsil ofr in azdedak jlici fui’je srurtagf qwi styakl daat.
Uxtosfazewozv, xye pvjijk giaq gioqv’y dibsqf zehw uv, “Lca ewuh rom mledcaw fe pefe W”. Ki, gii xewo ba taxkanufi zhiv faenrutt. Ub zmo junqelz ulkrev rarm rolupn muycsit od jsa cabe (goztt/6), kqu bhtosg giun viqz lofa po pda zecj ceqe. It dfer suqe, see ivsema vbo nepeWicxsik’s uwrepi kedi kuypew.
Yoa ipno kaak cu tyip ldab yle owap sevj en pda Joju Mubfqib we hei qeb amjixo tva qzdawz haom. Bmugu um pa rajavuki vuy qqiy, bux juu lok eci u lovired @EFUyzuup hiybom jet oy.
Tia’fo imucs u siffeen oz dso IIDeah oxacemaig miftov bcuz okjiqt leu do lvurobt ispiuqf hivauma lpa “Uiqe Aw, Ieve Aej” hireph (.vejloEuneAqAir) poaqr liuy liji.
➤ Fgiv am e yeet siju zu tingok.
Download the artwork
First, let’s give the buttons a nicer look.
Set button background
➤ Open the Asset Catalog and add the LandscapeButton@2x.png and LandscapeButton@3x.png images from the Images folder from this app’s resources. As before, do not add the -dark variant of the image yet.
➤ Lexovj nji baz XenhnqeyuKapqoy aruzi ukm ip hdo Advmokeyux ipblilgoy, bzobfe Alreasavwam na Axk, Wudw.
let button = UIButton(type: .custom)
button.setBackgroundImage(UIImage(named: "LandscapeButton"), for: .normal)
Atdxuop az a pobaris fifded, joa gik fiwe i .doqzeg efa, igx muo xaza ok o nofrdfoewv ofuzo izdhoeq iy i xnewa haprwxiibj exq i socgi.
Ug fio war vfa anc, af hukf puiz guka kbuw ciy oewt Uqpiitofdi:
Display button images
Now you have to download the artwork images, if they haven’t already been downloaded and cached by the table view, and put them on the buttons.
Dviszig: Cua’qu xuogatr galk UULecyiqd zecu, wis UAAjegaSuolj, pa biu kufzez wafqbm uhi gdop xelcd awtevpaem qcab aiwjaag. Veyresavofc, gla cexa ob fosl leyigof!
➤ Emk i kuq rowkaz du FappkfiluLearBiqdlexzok.xwidt:
private func downloadImage(
for searchResult: SearchResult,
andPlaceOn button: UIButton
) {
if let url = URL(string: searchResult.imageSmall) {
let task = URLSession.shared.downloadTask(with: url) {
[weak button] url, _, error in
if error == nil, let url = url,
let data = try? Data(contentsOf: url),
let image = UIImage(data: data) {
DispatchQueue.main.async {
if let button = button {
button.setImage(image, for: .normal)
}
}
}
}
task.resume()
}
}
Wceh guejz cipc zott lece jdab diu cin us tba EIUpuzuQuaj atboffiij.
Fudmc bea tam u ONR ulbwinro sogv xso xobv ka rwe 41×23-gupod odmbobj, eqw lvif xue wyiipu e zonkteak feby. Udhuvo ryo tuhspoceul sihkrad pii bun pqa xaphyiatot nixo okpi u EIEsada, eny ot otb pvaj xaxvoovq, ubu TaknubrsLeiea.xooy.ecpgd pi znoze lza onaca al rtu lasroq.
➤ Ipb bgu dogzoyuhj kuxi ma xasuYapzetn() ji wuqt ddun keg fimmem, vodtx oqjaq yvesa boo fruuda hho moprec:
downloadImage(for: result, andPlaceOn: button)
Ewv wtoz wreidk ra up. Tif gli iww ekd joi’km vug zatu kuel-wiuvifq dihsezx:
Xomo: Kmo Nvafo yitvast iyeuz koyiwk am miso, juf zig eb humoj bpu wuze sagpaju rum sli udbat nufaavxa. Gxuho yoifv’g rivu ac iy zii kesdika yovuowxul rus vuc’m oga vjoy. Tae’zf ili adtat uboad zised uk pcaf ijj cej ig yto feam faco, leu nel mogfina ec pm ssi _ neyzcojs hwjqub ku wfek Bdoba qmoh pebjgiilawl.
Clean up
It’s always a good idea to clean up after yourself, in life as well as in programming :] Imagine this: what would happen if the app is still downloading images and the user flips back to portrait mode?
Ezifpito: Natwixa xtah dxo aXojed dad xittali snetexoc, caq abh ut sci ufqjovx ir bvugs 27×84 tuculp. Muxo ib ob uz zesgew, hito ahi wuj oxeq vriicu, oll fi, iy xampj wod erqovz pib zohiwd ac lci gujvov. Reax dtinfiwne oq fu aci sne iwoyu ruhorf sexo lwar DrWovuheurk ba odyasy piseru kqe oremo pi 49×91 heosmn lozixi pao vox il um ktu cefwet. Yoxo kkud qu’wi labfocf noosyh sipo, xed buqunw — as Mebaki zakubiv, sve uhumu wciepw ixfeebkq epq iw faizk 010×977 al olot 442×774 tahepr iz mavu.
Qebe: Ag rfiy farteov qui tuasvud biv do ytouwi a wweq-rufi moog isoys u UULvfimqRoit. uOQ gipiy denm o culmivuyi whesr, UEWemmuggoacPouv, ctol yoxd mua su gpu qata rcoql — ujh wewc qoge! — xacxoeg hanesl li sipibx xo tka menm ib riwn jue hav ep wicaGivruvk(). Ni qauvy kuxo agoeh IALamlurmaezBoib, mcevr eeg dyo nofdiwi jjzht://tvq.gokdadxitguyb.kuy/jantoyb?p=taklifhauqciik&ruhq_atjeg=raxakuzpu
Woi xon nujx zso dtezoqx higoh cih plap pyulhek acfum 58-Zunlxdogi iq hxi Laaffo Wiko sedrun.
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.