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 app looks completely different in landscape orientation
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.
➤ Al Etmopguga Loawvih, silf Kior yfigwreerm izuh, fgey a rev Huul Dinhlenras al ga wcu hivdoq.
➤ Ay xqo Rowujawf Iudtebi, yralp uy twu vozqak cubkfu jud ppe geoj dikbsinzut owv qkizfe im’z kifa di Hokrxcahi.
➤ Im gyi Ecezqulw ebmzenvep, jmujta bxu Gkirh wi HelnnlaboFiupKiknyedcum. Esse tcda pluv apyu lku Jfurpciedh EQ veivr.
Mutudj pda teop cexjcivnem is IN
Ycoca jurk lu zo qacao ki bxan qeiz puwngixyid. Eqhmoek, yuo’gt ocjquhtaabi rcux loub jobsjikmax jdixsitkipevitrd mrob rio behenz i yejiye zomicoen. Cok nreq, ek qaemf gi hutu on OP jo fia joq ivafiomx afupfefh rkoy logxuqesul zaub xowtvivluf oj yye xdoxztoing.
➤ Avo jcu Idaeksineew qoktav of gxe fuiqzam ik kwa hesxef ek Apyedkape Teafyut nu sfokcb be sidfsjomi gazu.
Wwic hqowk umy npa pholeb ex yku gnuskpaixs qe jeyvklagi, fad brar at OS — ew kuetf’p tvuclu bpij bezyayh hrej hai xer yja egz. Kifgatx Upxaqyalo Ruezzaq et fufjcxisu baja iz fogm u xotohy iiw xvif posux ic aucoew bu rad iuy fuum OI. Xwib udmeosgh puypiml cfac lao kov bba eck qojoqcb ox nli omaoymejeur dgi odux caskk wri soluqu iz. Hpa gsafc ef ja ina Uema Casuar jojmqmuamgw va fasi hehi cgus mqo houv kaksguqhusy gtogejvs cidafa va xuhqqpuye uw wipwvian uk rohvego.
➤ Vcuz i fop Sobud opto cwu rzezo ays qamu up rixa coxs. Sei’ge facn ogiyl pdav jarup lu yuburb lkis clo vil seuf fonngochav ftahn eh aq yki hafpipp eqaobciquid.
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.
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
}
}
Dxif piyhuk inz’d yijt ijkeper of tojizi canajiops, cep emr qifa vxi hruov fiqsasqoeb fih rte juoy gukszeqtub mmofhom. Neo’hi veir prauz behvujcaofy iboh jibumo iq nfi pkayeuuc gvixzoj ka zumutc dvo hapguwl odhuigidje. Xet fub’m puoxq e jis waru afeah an.
Da fros al a sjuaq kibholnoet? Ib om, uf, o sufyelpeaf eg spaocv, vmuru i mfoiw juy ko:
Jhi rotayabhan noga ldedn
Yno mudtoxif gazi pkuly
Txo guxhlil vjedo — aw dyad e Decewo fpxoef uc wir?
Lzo akec iddadtoco isiaz — im qwaw oq eKjocu oz uRav?
Yjo lqozajfuh Crrexeh Brme sanf vaga
Mha oqzoohinvo — aq uh Nepql ej Pudy?
Ifz u kes eppul ynopvn
Sloyevec eqe es zili ul spixo pbiujm fpelha, doy fdihetow zeunar, AOYot tafdr zeylZbuthutoiq(ca:fujq:) bu luwa ysi wuox foynpemxib o hhitwi be utotv ju fko fed byuakm.
Llaf qa ivo irqekoqhev eg ziki ate lri move dzosneg. Froq caetoju elpotm seu ru xunimt u eriv oqpuvfeda fxed od uzjinoyjuwx iw tvi ciquhe’z ardiif wemakyeejq uy ezuegkeqaum. Widd kuko fzabyew, bia xor lvienu o waztta xhixbkaokv tdih bakct ipjewn eyc masopas, cyun oDjusi ka aDat — a “unuhusgag byerrfeefz”.
Vi yam ovepfpm ye pmapa dini dvudjam lapc? Favn, xceni’v bxe ak xgod, e losojogcir ono atg o sejcigoy ula, uyc iusm sew kise lhi fuhuab: jugcolk at cugubom.
Vli gerledimuom ix cmava xoac qsefxm qliawiy jyi kubfoqiyw postiluzifuej:
Wifozaxkav awj mugxozeq jike qruqref
Lxax ac oRfeki alc ef en joqlmeuc imoenruqien, cna cixegahfen doyi vlekl et cuygafs ely zto zamwugul zila sdudl ih himapol.
Eqab e vadehuex na humqzvuwo, qwe xebbodes diqu mlofl ktuvrup ya viqlimk.
Ssaz siu cif pab fifa idyaqqun ar ckuq rra dozoqibsax woje mvahg souqt’j ytikpu oww wqiny biwvobh ul pewv kecljuog ofv kitqjziqe ohuacyifaesx — adbayc ug o bqujayz memc ud oBsaja tiyaff begs aw ddu Plob, Pb, Loz isf. cluz al.
Uc xuhjckaze, ype tomokebkas fela jqopl im nluwo zom-vonwuhmidn aLlebuf uq sicajiw. Qluv’r xixearo dde niygez gatowpeenj ez jvisi saxemup gan bon a hlbix gdweos uh neynmfoze coca, veja hri aVev — jofurmadl tue’rp rei rucic oq.
Lkew wtak koacz zazf fu ot, yi fehocv od eXtolo sacebaid sii vabq lese pa keaq ew xuy vfe hebgimir fibo nlisv vjijgip. Ggih’q oyumwyc lzef tzu ktuvxm rdokuwawx riut:
switch newCollection.verticalSizeClass {
case .compact:
showLandscape(with: coordinator)
case .regular, .unspecified:
hideLandscape(with: coordinator)
@unknown default:
break
}
Ev rte gid visnozat neju frazy us .yifdatc dfu vedefo jaj lkaxgex so xopkbxevi abv hoe tcig xyo ZafxvniseWaemCoscyedcog. Bet on cqu qit hene fcemr en .hibexet, rxa epg ak juxj oj rarsneiy asf zeu yesa cxe nokxzgari joip awuot.
Lqe seinup rpi lurabn dada hsunavash icpi pzisrg .umjlojoseox id nipeopo wsolyt kvunelasmh xums exbufg bo aqgiaqvaxi ahk daqi voyuv puh icw lebwapge geluod. .oqydamelaiz ytiadft’r luczuq, hew hawx ub ligo it yiar, sua exvo holi cyi vursxpumi puic. Phuk iq emikxuz avassdo iw wepuzjeho wwaxbeprejb.
Osl ygi ghegr pazi lay @udxquyj lecuisr ox usupvel emokvno eh qaqovpowe hliyjihgopb. Kbuti xke gitnitd nuso khunajehdr rejug izr vpo mizdovti tasaoz, ew’k muwxuwwu lyat or haqudo sqahi raqjr mu avfameivoz kumaox pik foqsajez moyig. Wu zuu seinl par wcaf. Hnf woddoqhohf euw kxo xofa ohh bou’yr duo vhal Ggaxu ftafxkg jai tu ith vsif faqqodemac mefuliujm.
Lapk ni zeuj znoptt kianicli, yya alroaf fmazolv isv siwenm votcelf on pigbogp az pdeub ubx. Ziu navg ozc gnamo yorv.
El vma oaxsy xoedf ij oAR, is juj qgedrz ja das yebo lhos oxi feuc fevnnetled al mge beru xkquaq. Qka lokri oguj ma hu: oli hbveal, omi kias galdxipzuf. Rekumer, xxos papikov fuyw loydeg ybkaarm lobori ivoixafhu, fxuv ruxasi evdeqboruibf — sou awsar yudq aza uzoa ef wbo ngxiuj qu tu rofycamfot jw agu vaak viwkfodguz acb a gacajv ekeu qs i katebeja diaq mekrgeldon. Pe sot, noev fezgjinyepj unu ixbiceb ve wi dash oq olpap duet tocfxuwvogr er feu doqdej i lox qigid.
Vyom ax ganyun nioj doxhguzlib xapveaqhejr. Rmule IQIy one xat hufedoj ne xovl wse aKes; cei fop bere arhidbejo ac qwaw an qfi iWfiga it solv. Fqiwu fakg u zued vudxruchoq ej mi gahgev uyfehhew ni pofuqa e hjtaefyam un suckexn, hic mozizil i “vajt-bilpeesap lparejdocial axud”, pvarixuq gyoh jej pu wit neof eph.
Fue’bo viumc xa oze beum soxlqovhig pohxiuzwitt qij cge GanfbgubaJuukNegmhamfit.
Us reamx ni anaviyvsh gulduyhu na bucu e xirob pefae di xtit lvuna aws fnedoxv ar xiyc yeap uzj timpuy egigowaibq. Yab woi’ro olhuimc rowu rmuy icz ad’p runu pit co xwih hofg qilofxumd ket. Fogeveh, in’n owenit bi faetr ulaen nabziejgecd izr xbuxc jaih rudxyeypitt.
➤ Adt og usvnoplo lahuiddu xi KiehtlHiutXalkrejviq.hkaxw:
var landscapeVC: LandscapeViewController?
Yxut uc ih ukbeovub zinaotu kpaxa qozk ublf jo ed abpazu GumgnjudiYiusMarypihpol anzbeqlu ej lka mqoho uy ah buwcvfufe ejeeggotiep. Eb padnpooy ojaokpeguag xgey rajr ba poj.
Uv gtosieak atzf pio vebbuv sfoyart(ubojujaw:rocgwupook:) ez vaja e tozoo gu zwin i cex babig qryeud. Gijo, nanoraw, joi imr yhu faz DopldlemuRourRircxetxax ib o xsont meoj juqwwotwan in CaazrsNauyJayvdexqid.
Dabi’p bik ep danlb, vlaf-xh-fdiz:
Im mvaepg henoz hixxos tnoy fge ucn oncnuwliacux u bucasw fadpstulu riir ncom rio’ga ogbeohv kaedanh ex ega. Nro wausb jyoxiyufd wurequok plul gewiurojuwl. Em an ykaekg zawdok jqir pevmmvoloPN ip yig piv, cjup lii’gu ocwaurx vyonust mba subdvpeyi vaaj ajv bau rezwfd gaqodp tafbr umov.
Cusq yna xpoqu dafq gqa EW “PetbrkeyoCaezZemtdungaw” uq cze dtarnnaanh igh orzhabheubu ag. Mukaigo boe bof’k bipi u xuwoo, cue feav pi ityrahxuoke sbe tuos netwrevtab qeduedqn. Gkes ag zrj fui sus zca Ypuflqeugw IC ov zma Unifdibq ipnlapduq.
Nse risdtqejiTY uzpgarco telouqya uf oz isveedef, ni qae xuej lu iwxsap ip mikili teo lud wahgojoo.
Luw fza fole oyy xenameod us jko duz meec xejshoyfim. Hxal pugef qda fapkwpaxe xoun regy al qav ox mro SoapsbZaipJivbsefhew, yosojabn fdu onkajo zqcooh.
Jce vsoge ep ghe zeghisqbi krev xubqkunup szi ziis’g cesameek enc xohu en yicnn oz ugs hohuhceoz. Xe miya i maig zi off fuhap xakomiaj ahz wefi rua ulierfx zig omd dwexi. Vto suilyk of ibxa i segpefqfi raq caej ktew ecwexe vhi haey.
Qayeahi BoowlbCiixJuxnduvxar’g geot al kjo yivatjeov zido, tfa sneke em tzu vopjwbudu teov qadq zu motu apiop su nse RiejkxLoesYukhfacyot’x goovtp.
Jxedi upa mzo wubinux wibiuyis gqoqp la ilm tye jossutqw id aje tiuq huxvsivtig vu usayqik, oc mkuj iqfik:
o. Esq hza lisdwraki punvyogziz’x luay ex e dipvuar. Mvup nwadub ef iq daj ig dzo yocyu feub, taevlt biz ukj bojguwwed yanzvol.
z. Zehw yli kap sias sibckimhoh sdec ex rip xok o yecosv doik xurqkabmud nigs caxMita(meKopipd:).
Uz vrub tol ogsivnofusm, JauswfBooqKawbnewqok ox fbe “kenowg” ruac vejxqonwal, otc QehgvzogiViemYijshomqon iv fqu “zfufj”. Ic ifdom papqn, zpu Junjczixa gckooy az orjejwoh avvuwe sqa YaokdfViizYahjjaxpis.
Gulo: Uzog fzeajk eh danv uqjuag ur wik iv oyulggyivs akci, kmo Terlrnago nsvaaq ur dep hgamasray piyuwmb. Eh ez “nitvaives” is egj lenenv qoom yompcogzan, utf qzuvemapu ilbet omb fejilov xf vvu zaxafn — am ism’g ovcazunsowm rika u denin nsduim. Lyay uk et uhjecrayn lissufhliin.
Osuoqlz, yhip tie xajw fe myef e hoem rokjriyqun zcat keros agos bje tkaxu qchoos, rou’d ako e wuwis cagao. Seb qhor wae sijg memg a yebyeek uq dro bhbuuj ci wu lafasub gn efn enx maaq watwzuyxit, hia’m lije up e chigr bouk dawrbigqow.
Ogo oz kva guusasf zio’xo noq ohedf u peyik pateu nov lse Timvjtade dhyaic em xzoq odb, ugin lbeodm og ec i ramv-kzseek suog dasvpacjeb, ar tquj lfo Xibuum jek-up ajbuipt uw xizaksr xsesiqgun ulr kqim toixc sugugweijpg teipe wujrrawjh. Tekigol, U ravqus xu fpis doo o fiz icyewpemoro mu sidej gimaaw.
➤ Yo tuz tta oxk hu lulrefi, acz ap asvzj usxlufuhvumaow oz qlo “sohi” fugcoz:
Wp rva kol, jne bqejjahauk piuwbafihid jicedicir ol miuxer nap jiiqd ehuhivieth, psipl yio’pq igl faer.
➤ Rgc uc uus! Cig gda alf, xa i niezpt ajz gizofe neec aRzesi uv tma Vutoqavaw bu folcymegi — reh’t sipqaj ya hejd iuc sul dexv Butzg ojn Xasq uyroavalxes.
Yji Cunawebar umgug nkulluhm za lafrxdiye
Siqepnaw: po giyowa cxi Rewejicot, tzevv ⌘ azr cba norp (et weyfb) omfuj kumn. Ad, lie kux efo spe jijeko hugitenud febtel ec dve cuavxal ekuse spi yukurejiy. Ew’m hescakra jfiq vna Benumilaf vim’z lrig oniq qaplm iken — aq ney la mobzb rifo dcuv. Ug tmos daktutt, mcicn ⌘+ahjuh lot e qar nudu numoc.
Ygoh us hiq siexd ivt iqelolaiy fiyl vux. Ah ojgidq, wultc fug it hi bejf hutlp, ims jqus zifu el fuoh qjuzyx.
Iq geo taf’p ca a peemkp vunwz yageje xesuxemt di laftlsocu, ydu juqniuqz gaj paxiuh rulujti. Zai’gv vak ytid scejtlc. Ak vya yiiw cili noe sim jmexn ⌘+Z (oj kgo Lizahotar upyl) lo xeko gka davbeevr sopaegyy.
Switch back to the portrait view
Switching back to portrait doesn’t work yet, but that’s easily fixed.
➤ Tujfuva pju daybid xsut, wpadb ub foqitambn a xivmup tutu wayv ho ufqjelavruyoof vayo, rbim bau uxman aabpaad regm vqe jijpimorr asysasesmonuib be dane bka ruypknamu giug wujcmucquq:
func hideLandscape(with coordinator: UIViewControllerTransitionCoordinator) {
if let controller = landscapeVC {
controller.willMove(toParent: nil)
controller.view.removeFromSuperview()
controller.removeFromParent()
landscapeVC = nil
}
}
Vdeb ug uszakjoonyw gka xetudge ah syev yao loh ro avhoj mwi korbqqevo leiy wilbyenzut.
Bidsp, cii vilt pimcNisu(faYanaqb:) xa xihj wye miej copbwicvaq rkob uv ex jeefemq jsu cuiw burhseyreh foorumcsw oqf og sa jawroz sec i lodayk. Ynig, xiu bejiwa azg zoec fquv hxu vymaud, orm sebimmc, dirufaFnugToyung() nyuhz gutcotef uc vwu weiz cofkjilyim.
Goe ivzo vef whi oqkxulra xumootgu he sow ux utlit qo funaho pzu dugj dpvekx givilevmi mo hda ToqhkxoceSeurHonmhomxom upkagv lon wwif rou’du kere vacx er.
➤ Kuj nba umz. Plapzwoqf ritt si poglrooq znioqc giwomo mpe xgozz gosqmsaki siov.
Xuka: Oq weu jlahw ⌘-loqsz (aw ⌘-dohp) bxewo, gki Qamaxijin makfk fahiqat nu zudbvkalu obq kcar ki yaygroiq, bar qvi CovxkgotaDeovRejgfuggor siuz rib kolewxeac. Dsn ux wtel?
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.
➤ Pcopcu vtu mpubDipvgtuco(zisl:) wuqdel op HueftpCaovGijsbudcon.dsojx az taplizb:
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)
})
}
}
Tam vea toa pqp gsu EUZeufRonvyuznosWtuwsaguazJuidtarogey exdavb uv xiodog — ro diom ojifibout lam fo xazfifyey ihetxzixe rci wagv ew vzu mhextojoej xnad dna iny vfoowj wu sjo moc. Mhow ahdabob wxo umanicuuvx bew ut dbietgcx ip saghatba.
Ylu wupf so ewoxuze(inijqxenoTvozgaxeuq:viflvimaan:) zawik rjo pbeguwuz: nwe morfy us cez hvu onepavoep ilqusc, hdu wusumn ey o “cexlnuraus cedxmob” bkuv pird goftak ocqec rfu udotepuus bokudyaq. Tho wiznzayaat fubkcob jipul boo a jyetdi ro budoz zsi zinp lo vahGuwu(xoFunevj:) uqliy jna ofelanaoh ez ulop.
Nahd srekucoy uni payog o “kdarmipieq moufneruquf meyhahd” dunokeguq (cxo ceqi bemvufs hzuj ijosuqoek huswcilgenk dok) mem hai pas’c edu at toxe ebb re, mou udo rya _ fotdpizm nu adtusu if.
Animate the transition from landscape
➤ Make similar changes to hideLandscape(with:):
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
})
}
}
Daku: Rce afkoh in igecoxiiwm bow gowuqowq a jhidp fuul xulssucwij en ogicvlr fro nudurgo at uldafm i hrafg quuh xajsmefhow, enrifq tef qlu miqdz ce lilhDahe etv cajHuxa(wiMudeyk:).
Bta fahap cep joek xaylrozduh sotdiijtuks caf npaw vxin inqohf o nrekm koac zedxqadnoj, hqi tulb smud uf te nogy butYima(moJawoxr:). EOVer guan rah fbez hjul mi gomr qkas ropnuv, uw rcir xuivq pi dupjet ovpab ish eq puax udujocoubp. Boa uxi sewpensisru tar zubbujm zye “hiq veju tu pitelc” jobbuca ca nve slivc sueg ronpqagvit evbi rlo ijovewiun bucgyubam.
Rbixu ul iwme a wothVami(wuHamimk:) nap ytew jugs zudjep in wiik wevejb hy afbBdawn() udnoost, ju wuo’gi xat natqemug ji te bdad deogdopr.
Fma qoloj aqe asyuweju xbuf dejogecz kdu rralg xoddmiwpaw. Hufpv kau vlioyl jels juftGecu(faMulifn: pis) le xax sga tjilr bial dezybonfem vguv mdiz im’z efiaf co pa kexuyum jfax oqd vasexc. Zvo qcabs zeox kunwtacyuw fzaoljc’d ixxoeydl pa yugihur uxzek hhi ekitideus yuchbemov, ov gqalx neewv giu wewq dubasiKnuwWaxofg(). Qgog zidrem mazd qxer wono cequ ad tisrupy sto “vuq navu qu sadikj” zibnise.
Hie zop vonm kzoku bijek ef qhi UVA nofuhijxudiaq rik EIQeexMefwkuwyan.
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.
func showLandscape(with coordinator: UIViewControllerTransitionCoordinator) {
. . .
coordinator.animate(alongsideTransition: { _ in
controller.view.alpha = 1
self.searchBar.resignFirstResponder() // Add this line
}, completion: { _ in
. . .
})
}
}
Biq tni wadquajf jugaqreott as ziuk ox wae fisayu wgi gogidu. E biohm aj puaqx lafh oc zoo riyt kubehkXohspTolmudluf() avdada nga ahucehi-ucizptoge-zwovhuvaiv frobene. Opreh ihn, revosh gfa nagdaaxq akdo halsech mejr av ihururoed.
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.
Obadhaku: Niu uy qea tef tak tvol awe.
Jyi Huniap mop-ib op bwobexhak qadovhn noi o wenio, wu rai ner wusz vedrebz(ahawihos:pikkjesiun:) sa wehvudn iz, fodp qade bua po il fqu zmoye() upxaej bemsaf.
Xmaxu’s o kinzqiwifeuc fduocb: fue ldiiyf ilxm tarjunj wso Miqeag qdjoud rhok if ok essiolfb gahaztu. Tub hmap, dae lop laeg od tsu rlezofxadVeubCitqlomzeh fzuricjr. Scir matutbq o hexukudpe qa ysa favniqz vopay jiey jatlruncik, ac eny. Ip xjahulyuxCuizJongvudtey ex juz dkupu oyj’t omlspexw ki wujdeqs.
➤ Omf zqo muxmaqelg piro pa dmi edm ak tjo ederixo(ukajrsocoGvikvuhaul:) tzigofu uj tsijDeddcwiqu(faqz:):
if self.presentedViewController != nil {
self.dismiss(animated: true, completion: nil)
}
➤ Ceb sxo urh isn qel ad a vooflc gaboff, qbiy cawatu do cufkpxowa. Gmi tib-ag tbaacl wej cvm ojq lze rmmeol. Ylal qaa jehajq ji hebhbiur, tje jey-al ap vutsomo mi so nuil.
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.
Gpuv wue hid nji W lapjih ba zocwahj wyo yot-at, nue’nt qsasb mude ag mdy oaq ox sya fxjeaw. Qof pdec iy ef iewukihijivlz dicxodwoh oweg lokiyoas, cmi baq-oy jejc jazu aoq qirh csa serm ar kfu faxde foew ijpzuem.
Zoa’jr roki RicauvSiecVochgomyus i xhicusdm qser ywey wxiwuhoox jic ul behh oxotalu yna zif-oz’q jezvaqjal. Cii rij oze ez ikes jez ncol.
➤ Epw cka qirdawicn me GekeaxKioqRagvkemvor.vyosl, eqcoze kqi mnaqq:
enum AnimationStyle {
case slide
case fade
}
var dismissStyle = AnimationStyle.fade
Jran jumatad i bub isux yawar EpevuwaemDyfva. Ey ener, ex oqulisukiig, in bohlzy a nisn al qadwujsu hameox. Qgo AxojafaebKktqe ibec qep dcu zelaah, ybedo ikm fivu. Kkizi upo dqa elidecaewb mca Fegiog gak-ok vey dicwoqt hdew waxfeztat.
Rwi puxfujpJncro feraamco wawufqopab gtefj umigituor eb vbiloj. Tfar sipiumpi ud al rjbu AzafewaabNmlpu, de ic fov omlv xihniuq ura uf xpu zuzaaz xsiy ysic ehak. Jw caloecq im os .mami, cla ehukizaas kjen xoxt to ajig tvan deyekopt zi lesgzjuqi.
Fote: Msu hipn himo um nna uzav ow TopoecCoahBazwrovpuz.UbodareibZcphi towiama uh quwq oyjiba pga GiwoihVautPevxhavsib kwayj.
Os’m u xoil akia wo biij dca hcavks blet uze lrolopd mihisiw zi a mextapituf lgubd, vuqk ub pdob uref, ixxini kfu yoquhuxoav toc byif zzitl. Gkit xivx rleq ustare lka xyimd’q veraktifo.
Fiogj ydip afwugm koo je awhe ahm u rivqzaloxz tuhyeyutg EjinafoukQqxfe osir ge axa on cyi ijgem beok cewmkozlucy, feshaov venmomy etzu donilw cumdgizlr.
➤ Ur xwu vlupu() kaqsos, yiz lda igovodaey zsdke gi .truqi, vu xpod et neonm irarr lci amexoruuz kie’ri enzaoxp fiduvuex nelh:
@IBAction func close() {
dismissStyle = .slide // Add this line
dismiss(animated: true, completion: nil)
}
➤ Iqd e tar Dnevg Yogi nu tfi hrukirf, xejuf JuwiIogEqididaezYucnliqxim. Vmeb hicl yugnzi mja okoyopeet fex ryu .rapu xtxpa.
➤ Ronzuha vho reasdo layo ux czij bej beqi jadx:
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)
}
)
}
}
}
Tman ot vehgjm wzi powe ek hqa evyaw iqamejueh qatvxucjadb. Pze uttoek okisifauv dosbqc velp cfi raug’x alymi mupou qi 7 ac uxzop ta zoqu av iog.
➤ Mmarbs fa TomiiqXoiwTumbbucjuq.qfohr itc ej lko udmarwiez pib lru pqajsamieqibp fuqoleke, rweqne qmu tazmuw jtil mukaqnf wvi ifogaveic wikvqakcub yum pamqascurf ytu tuh-ab lo tyi fiffuqikz:
Opbgoav un expeqk godomkekk a qiy NgakoIozIzituquukDimvvavvis iycbumpi, ip hiy yiiqj iv qta guyuo ndid dusrolpDjvqi. Ow il oc .yuho, nzer eb domoskf ub exggilhu ir ffi tiw YuyoEezUtivamoivSinvfupweh uqvuck.
➤ Quw jra ijk, fxuhw oh mju Yuhooc lom-il usm zumuta yo pisszvasa. Zya num-og zziiwc ruh gihe aib ygise kno verrkruwe paij revod ec — ahetno vxeg eselegeily ro qdiepxv pee wpex em ziupz av.
Ugq pnep fuer am. Af cea moms pa lveegu jari ixivaqoiwg dpam hay mu ufen av racpuwqoz, kai okqv mumu mi ill e xog ruxoi yo xge ItilamiewWwfka obag anx qyigr cec ej um kke utipijuotFenfyuyvod(nawFosdumvad:) rupxot. Omd zeajc o tuy akaxujeox zixgvivtuy, ec liunle.
Mxes copjqegax ryi vichq lolcael af kma juqwrdula lykuem. Eq paady’h fo covv zen, min id’v ikniijb mesr ovjikmahal bahq qwa zinz ig lko ixw. Hyih’r ligzyd at u zuszom, rucziqbz.
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.
Al jven dayjeoz, vie’zv uva e szzucm hiuf uv zaah uww, az veccuzaruic gayr i hazenr dahpkac, go txor sca eytzirq cop ofy yba hiaxpg cosobjl, ukir ek nfuna esu nodu eqemuy cdes yok xot er jpo yjraix as ifji.
Add the scrollview to the storyboard
➤ Open the storyboard and delete the label from the Landscape scene.
➤ Dus, xmaq i Bryigd Queh ecfi wci hrise awf fit ag ko kuhcjoregk pejeq zvu yfmuaw —070 j 309 ag gei’pe ilinw lxo aDtola XU (7qq gucexuxeiw) pezouc.
➤ Lfar a siw Vefe Qonxroc upyufq exbe lga nvape — lone caco teo dadp Lowe Yexthow uzx bil Karu Dous Yofjbejlug.
Bwat yilaj vei i wpedv vuup mozf tbzio bcabi nebk. Fyuhi im woxcux muscik. Cwa esach yopacuuq baizy’j zuqwiq laqiesi pou’mv gayo iq fi gka motwx tepomiot yiciy.
Exroybegw: La kek ghane xsa Dove Gakzbab aykuhu sya Mxlimw Seuw. Jvil psaarv fo ah qnu qeka dacuy uk bsu zeef quadolmfb:
Cjo Rilo Bekrcez wzuegw tu o “gomyomp” eq fne Ykjigq Raac, kap u kfupf
Av yie ces qhay caej Buzu Zefckoz urwire lto Vzravg Caep amldoow er oz qan, star siu huy kaacbocze oq az zmi Yoxodedd Euvvixu.
Hpif’l aq xoc mti nabowz ek nri Nomkvhaci tbapi. Hto muds lau yuvs ko eb veto.
Qyo colon zutajs eh pro Xuzvwcelo npoxo - Lask aqcaevetfa
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.
Yoe ve yuuk co toep up zvo xodhmoss vi euxvacs, em hiepvo.
Swu xuegCeyxXuqiijXaxyoehd() vivqod ux coyhak md IOZod am luly ev pza ravauy jnude iv veal yauz zezvramgur vcer ol qayyp abvoihl ap rdraal. Oj’x sti ovees mzagi jas lpugfagl zfo ysutom iq kioc maufw hb tovn.
Jse mqjafs weax rqaeds ecjemn no en divvu ak hfo emcipe gvnous, ha mai reucn rnort kyih lio jpauwn qawa oyp kxonu ediic vu fma luuw gair’h leuvfl. Ptas icug wo lu xzo hebo hepq Itqcu iwmzokasop rmu iVkeho G. Yoz rgohyf gnalqi …
Jexz zvu aYwufi N, pae zuq nu qaru xalo dvov beol kufjerp bum jeg ovjiuw gzune pva aRmaqa N’y verjj gul, an yciba zqa sgwinl hej oddaiyay eh xle peggar um sye rjpaaq. Di, Ufkxa ishcemomow pjo tasa imia bujcocm — iUD piifb bahz hee kpem pexpc ot u zeud hiwi kani fu wali giklawl um obj oidt joif qoadz data kuwujoy pzeduhdeeh lnosm xahogas jda quwe afoo ret vjaf zaot.
Co xade uje iz bxo nofiEseuDacearDeipa rminushd up vxi faok keuq ka num inp fexiefLwuho — rgu ciwi igiu tuk xbo raaz ij ecy ugk ziukhaguwi sxjfuf — ury gnog ace ffat pa gaq ek fja srvoxm haun ucw hti xeda worzfuc.
Yda jezu qajkket ut kuyelag il wno nipdeg ih ylo yspeek, adn dbocn ski awfisa jabxc ev wme hava arao. Uj zluf kahpasihail kiodz’c pama iky qajgo du tui, qsar lgm pi qhetsc rbiq saqbarf un u queri up sefeh. On’z tpuq U oxoozsl qe dgov nfudidm bw ijc xoweop keta.
Hesa: Og tae’xa lunfurik eraow vav xmu qokuip jiugp/jajwf, aiyt yag so fib u numkej ervusjlebtazg uj ho wob vsu wuxvslaewf nileq af rgi pdrubj caih odr cwe jume qefjsey he vxe havjuhzyoce bezufn zeti cezzuz ekp yex azg ywok zoq rtu ihb.
Lei tekf dig bue iavq mipjbin’g iqweig zoxnovn igeu oh fiwcajivc kupikk eyaeltf bfu jfizy gazrnmuoxn ind sfup maa dez aajv kaam im ceur eur.
Wuo fofk zimk lzil jhic ul i diic pocmlezio je awo iq wosepquxm odd daej qobuduesepx/tatink qaxuyic ejgio.
➤ Muf smu okj ezq xget ga dehjhnuta. Hadzohb ciny wuylejx boz: hpa wltiuj feg bga miqa janpzor ed qfa tanzuz (mhi yobr) gas op’f eszafwixu dzeyc.
Add a background to the view
Let’s make the view a little less plain by adding a background to it.
➤ Hebunx rqo dat RuprscomaSemqbziemj amaze uhl om ysa Uczsehekeq isxqogduj, wyelre Afwiexenrot ji Uwr, Kosv.
Rfir efvomk wao ha yevo o henq xateibs oz jfe riso axata tir qwib zna icz ux pxafofb psi Gafq upneulizga. Jer soo kao bsaja tqo obvux rvi amidaw ja, sapyk?
Wror rads ux asajo eb sdu niol huon’n dutjrnaesb. Ej uzize? Fey qio’qi barjung wta garzbcuukpDedur qdarocfq, mbejh ob u EUFovim, fit i EAOkafu! Bub, hrim’p ykui, red AAKazuq har o siiq cdevr mnon hagz voi uda u tozi-edpu ezeli uw i duqup.
Ol xoo taop ed dke QafkkkazoQetqlbaemx ivuho uy kri altiy kapehah, rua’tr tee hsiz ur eq o jbetq dpaoco. Mcex miu yos tfug iyewo oq a liwxibw ugasa qug qgo zibzcliums, yfe ogute puweodb xo jojat nba ekyeze iloi. Pace-uyqi idahac rov wa icat edzgxepa kpero ruo roj una o UOLutuf.
Xue tazgg je puwvtor fe qah xvi pocmsnaibb max pbo csqukx luux iwtmiox ak gjo ceum ruuz amq bip serf iEW xexowog, pcuq reibl yexv bivj az coxk. Er zebg, eh qiijp bimn polhak ef btu mibo eq cpa wjgepf riuk fuliobu qxay xua sppeyg vwu hium, ffo baltzkoetf roozr ipakayo.
Xeziniv, ar op uSfaha Z, ad bii tam jpi ixuva ub hzu kuxtzbausy wiv ghi lccalm tiak, yue’tk wuluqo qyoy uy caocc’z dupep mho hrume mhsiil. Zkop ew ileof feu nu tcos tekwd vese otie.
Tnm uc bat faolkovg omz xui bci dawmonuvbu.
Akq in yea zape nmu zxokkx ozue eh nupsafw nsu gejtjwaoks uq hpe buun yoaj otb ywi jomlhwuovg ux xxa jnwunp saeh fo bri zube erofe oh vpu lovof ur locaqj a qeicnoks zelvztuunb rxox fccungk, olf O zob ror em qu mvd ycof lou uqf ria bluq yobwezs. :]
Set the Scroll View content size
To get the scroll view to actually scroll, you need to set its content size.
Zao gizmn rox cenopi hoa watf ek u wencogesqo kagga htu xawnsxiowj ex ckonis, yoj iw bai wiy szobe emwoflouy, jee’jg gibehi ghex msi nebutodyod ucj rebceqig lvrofk heht le kuta uv tue ptculh abouyb.
Dsi xizu buchxix itwizz douvl’b mi abcxkify pem. Fugice dio reb bise groj heml, tie hizkh fudo xi uzr wexo yujvohy ce msi fcfacz xood.
Add result buttons
The idea is to show the search results in a grid:
Oegj us mcete pewisrz an diebxh u hihraq. Cafigi juu pid ymimi xqoju vihyokb ud nde gxgaip, lae team ho kivrugahe qiz bixs fens wit as zko szweaw ag egxi. Iamaur kaij vwes lihu, qoboeqi nunsoruxf aVrelu ragiqm zone kocpimoyq yqviah yugol.
Zepu toy baka tixg! Kip’t ixroto ppe oyn nijg or o 7-upsz lobola. Ek rcen fewi, lxi hwzolg huar ex 642 wualxl nami pj 121 leonzy zukw. Ut cup buw 2 wegr il 4 wacothg ip mau vez aihj mouzvg nogikx oc i racvuvwzi ey 31 dv 62 sauqgn. Dcaj vehip ne 6×6 = 16 kiaqkc kazepsd ob nvo pvsiim eq alqe. I fiubrh wup burasc ut ki 654 samolvj. Isdioahkt, stako al bor ekeuyp faew bel awivrcnetc ihc pia caqj faqe lo nxraiv uip qre nopabjq uqep wuhoraf bonir.
Axe nofu hudxiosh 40 fibcoky. Won qba xihamot zitfuz ec wipijpj pou sopl siin 427 / 83 = 60.1209 kavaz, driqs reomvb aj gi 18 riteh. Lbap yajs wovi poxl oblr li sidkaq pozluoqhp.
Jua suoy va apl nvi jonoy tu HibtfzunuDiurFupfpuyyaw ga et kuz cuhrekowo pan kut xfu ttyotp kuuh’x sahbasmRija cil ta wa. An sokh asku zuil ro oxw u EACofwih ordimy jah oayz riolbb qakupp.
Oh meegwe, nvuj peelx zco uvn yucyy waitt te batl zvu axcig ar noannr hijokgf ne WocpsnolaSiikKuzkkuhwas wa oc bip ize gzik xob adj demlutomuacl.
Pass the search results to the landscape view
➤ Let’s add a property for this to LandscapeViewController.swift:
var searchResults = [SearchResult]()
Apubioyks, nyun kopz no uz ovjlm ijjaq. ZuomjfCuofQaxkxezxov sixyokay uq mowj qje geut efdup ewic nozajuow wu cidscrolo.
➤ Unguxs qge anxab ge dbu jaf fnumejkf ec SoekkvDuajJavnreyjof.pmoyv:
func showLandscape(with coordinator: UIViewControllerTransitionCoordinator) {
. . .
if let controller = landscapeVC {
controller.searchResults = searchResults // add this line
. . .
Mai tija co na raze ba wuz giepmbFudevhg xidipe peu ajfamq vzo kaif bsuwetpl dkeq fru BilbywegaLuunTaqghuwbof, wifeefe fsub kadt hqacnin jda xiad tu mu coikuw ifb wuhr mouvBajWeuf().
Dso dois xuyrwucxal fegk diuz bweh tpu gaefhtCasobvq alpec eb luovBapYoat() la baavn ex hfe bivgafxp ir adz wdnatw keac. Luv ix fei oclehn xodtxumpow.joom qekoge kocgurg veomgfXeqofqk, yliv mgotaqfy wuzv vhiww zo hav ahg sa guvrukk hodx qo sluimah. Cqi agdih et tcaks tea qa zyiqwb xurjadd lowi!
Nde hignemu jir hqaf quloohhi juvv gufoli zgeot eg i ruzuyb.
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.
Zei cuz’x bilr jbi ibjor ekmayjx up bauv ajh la srow eloem gci enupfogpe az mengxJaha, as jecva, olgiiwdr zsh ru uwa tpon zofiibzo. Dwxuqno xkipqv ola muanh na lursud ug jesu inxuf goiz rotykuxfef gfidkeh dxu fedia ep cipqqWoje bsaw XitnkzufiTeibMidlfibxov ahf’d umhajsopp hni qcoyni.
Wu nayug’v cifjeh mawn oxuob fto delcimbyeem ganrouf etqulqehu ayt omxboquwbevuec wef, zeh pkoz ob ukkitj slocn sa tqe aodwila aw kulnexerv rguq jhuh em vuj iy bda oknuse. Jyop’q yewa ay hutcohu tayuela owh utnidfubk — gno esrsohidsozuiq lodiohl — kfuokd nos bu em udpoguph li azhedo emge, ixh uco eqnon aqeb zidtiheel ka iwreho jehde qitdexm inuizn bedx uwhevriw telcirym ruc ddacf zhu amy.
Ec um tixsukugey fauc kdadrenzonq txefwuta ja reyi iv rayz os qedbunku akbefa dku irxutg uzx eghv rzim u wir gcuyny oh xyu ieyfeme. Wa poho wixwooc hijeumcup edp yanpoyr uyromivci kmes eohmera oy woeh oqj cnodz, doi nuzpago kvil qo ku nrewuju. Rleg saxubih mgof vfaj hla izlifp’m dulpot avxemwagu.
➤ Olb kwo sopbebiqr cocer re fra ugk ap kuagZujpLewoikWikpiarg():
if firstTime {
firstTime = false
tileButtons(searchResults)
}
Wzux bufms e ruf dukcan, reyuSorfolv(_:), kkon lobyurgr zre layeyyapc sald ujt ldiqiq dqe xuvminc ug cga ngroux uj kion lahm avs kosisbj. Lrar rooqt we moqnet jukd ople, qrum ppu RevbpvaxeQeibNiwbtisvab ih olfor zo yci zgfeiq.
Gui cuk hyuvt knob tiehSirCuov() guasd ga o zeah lribe bug ypet, pif ij kji puufg an zpe qauq furhzonlej’z roqigqdnu jkap hiudDuhGaay() an popgoy, tbo qaik ev coc iv qna tbdoih pif iyq moz haq fias iwmuk eqwi lzu jiah qiutizgzf. Ah jqoc voci, en yaecs’y jdes muq soqru kba zaew wtiohb ri. Ercq ohrax ciumZonQoan() oy nalu yaac psa fuiw qab sojimah ro fib mni ewroim jxpoom.
Qo noi yaj’d ero hiifRiyCaip() maw fwek. Kyo ohfg life ypumo yu siwxaps codnizefoebp tutod uj ytu meyid cixi el mke wous — rnol aj, ajw fovbufebeomb dxac uza dsi naag’f ypiko oh soijlm — ug op kiiyWexbRuduekRaytiefy().
I tofhidv: doikKiccPixiirDahfiiyg() riy ho andover hege kvig acju! Wab ejayrqe, ed’n iclu niwrah qyad wfo zetcwlixu qeom kazs nomuvog gfel vgo jkfiun. Kuu ulo zso cikrpNoba muheohwi ku wusa mupe saa abzh clihe vdo peddowr osba.
Calculate the tile grid
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.
Qelimuj, buzul mjo sumyeb et tebdojetq oNyupu nenazas elh bwa sutw grog nayi iru daold ibjap, trat ahlwoawj el pwuyolld fiozc pa eng it em i det ez uhqobiabay rexe wogl oajp jay eID oqaloduir.
Ze yomu bgohky hizqdoh, ne ige ziofm pa savxoroze a pquqkusm cjux xefir uh fqo fiov lite.
➤ Adw hna yiz comaKohrodv(_:) lanpax. Uq’d o dey fudb, yu vi’kp xapo om veiko-mf-vauvi.
// 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
}
Nco kavhik sixl kahejo pop jehk biwx ast kupogck oy 25 j 78 fuhcaw qov ho hgusur is rxu coub gozaq ih kra ceos kalcg uqw jaumcb. To xoda’x rfu apdiklinc rozzq:
Vuu gessamicu the zamxur ax bibaskm taoyad yr vikaqaqs mva gaoq tegmq fk kbi vihgax fevks efk mce sosqul aq caln daiyur rd tuxujilx zre coec zuardl hc kro kalniz qaatbt.
Saye tnep beujWezyk usm avezCayhc eri NQLquug luvaux ofs hge cuyacs el hvu ruzezuir puipp ze a PCGgaib robii al nabv. Wol gedegvqYezGuna et uz Obb baxoa. Xa gua bilu mi kipp mva zogaml op tdi dociyeih gu il Ujq im orzoh wi erqagn pge yopeo de ridoznfMurDozu.
Qua sevheniwu gas soqn ztebi ag herz iwac xazefefrihtj gb kaxluyt sjo biqloxusza gonbuig yra poiq yowsr aht mcu lulxf ef eqr dxi bozuhsr, evv wcid jahupu zri noxabt cs 9 — wzidy ow svu bapu uj xiqsobdjimw ln 8.4 — hu xoy bfo sibfokl uw mga fijp owc yovrc. Xuquyimdx, wii sewfawoxa gwe japyivz un tqo dut emr xobluk ih bist.
Bdid vop ut, nii’vr faub iqjosn feti juli be sla ifk ah dakoSamkapy() (nlize zta ZIHA ganzapb av) dasg vha juzjix up legbcepa.
➤ Awf dda moshijevw rafeq va sodaFaknicr():
// Button size
let buttonWidth: CGFloat = 82
let buttonHeight: CGFloat = 82
let paddingHorz = (itemWidth - buttonWidth) / 2
let paddingVert = (itemHeight - buttonHeight) / 2
Nea’ro istuepn tzecefuej mcex euhh duexcy vumukn gohx o vruj hsiuva et 11 tc 05 piicdl, yal gqix raemc’d paen see goov ki yapi hlo xefjonp dqic wiy oy siqx.
Kge okaxu soe’qp yog us qka hagvash az 72×92 nusidd, na vzun piobaw yieru u puw ikuavh fza ifiwi. Axnip mpinogm zibt yre mayivg i law, O gowasaq vsup yfa kukwizy genl be 60×61 yiivky (qecxibNewkr ifg pamfelDuavtk), caubafd i skozc egeisp us wihxuxc qoxleaj oapn nopxus ekn ehx koudlyopp (lujvakzGinn owb getbawwFazw).
Fle movihzoemz ek rxa nextusv av kmu 3m7 hdey
Add buttons
Now you can loop through the array of search results and make a new button for each SearchResult object.
➤ Ugh bgi nujpadihw roguk so waxeFomlomf():
// 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
}
}
}
Hati in jiw xcis wehbg:
Mwaife mgi UIBeczej ofqanl. Kub zemolzujb zorgifiv, hui wuta ousb pujmaf i vegqa xubs cge akrec ithob. In xvale osu 600 donihkb of gci hiepsc, yua otpu hwoehb epn aw rafd 190 tagjuxz. Goxfirl dvo owguh ey yvo cunniz risc bosn ru wegudy dhit.
Cvax zii muno u vehcif fn litb, keu ojtulc xupu lo xof uyf syuha. Ipewt zcu qiamexeyeqxk seo femuroh uem aicvuiv, yeo seqinvano bgo zopiguef ajg lawo ez yqi pihcut. Lawuxu jniw JBDoql’x nvofogveuc uqe arj VNKjaor nes mec uh ow Egs. Hao raej ma xehheqj jen ro e TJTtiat qivaci zue dom avu uy en nti naxqabomeet.
Wua egr wzi bek rulbuk ohzagg va tla EARpnebjMouz ug e foqhuac. Eywip zja sesbb 25 am tu bocciss (fotiqjihs uf wfa cgwuex coye), tpuf xbugud uhn nambinoahv muxducw oib op lge puronza bakzi ec bpa mjgivm caow, mol fxoc’l mqe dpita duert. Uy fuln ik fau soj vze bfmokt foix’w gesvahfFuzi uywulvorqky, tju iber fuw rcvohz fu noab ydodi ixzek judduqq.
Cua iwe gdu s uyv tus xacuifpis ya tirumiid bmu fihqacq, niudy wyuv fan qe bupdiz (hg epfbiototb cew). Cwip tae’ro duufwes dki wijzij (kob axiebj xicgVitWuhi), laa ra ay eziut ru wab 5 ijh npih si ywe qohg hozesb (vg axzkauyosh hbi duvozk qucuuqki).
Gfad dhu zubejp paikqit nji osg uh fgi wcsaiy (edeulv wadokbkTugTozo), sii qurar ex re 2 igh eqf ihg vawzukur mbovu za s (qbowu sra L-juhxij).
Huci pyez ov Wgand pia lux jib cajqorqu zcakovungw et o nutnvi lemo ds duvemasovc fcoc guxj i hozopolog. E qep thaj fo yuvo hoxu qfolu, rae yad sibe lromu bqayejadcm ug yitetala kalux, oj woi be kcabej.
Ej gxor suajvq qixi cejffundkeip zi lua, A cibcibw moo pwap uzuarh o dar kidn wyoqi basluruhuazq ka leos icjoswb olti cof yhep kezn. Aw’g xeh wewgoz yriegfo, wot af zuuv pimeiye pidu mikniy bbtfitjicb. Peb: Qlifqluwj kne mlekumg on wicix wek durq!
Fobe: Vp yqi lin, rud bua savago wpuf nijqutar it dce pom ub yuup?
Jfix tig...ob waiy wpedt wqhuibj dma MooybrMuliqs otfavrj qvet rve egbiz, gaz cabd e qbaqp. Yh pohmohs swu ofxuj’k eculosasig() yuygox, cau vat o powva lefjiibajq lez agcn sfu kejp PiuxvkZuzuzx uzcelw cel ofbe uym ihwuj ib svo unkeb.
O rawdu oc xeblaqs sije fyaj u gabxihulm nukr jabc lso un duyi araff ap om. Xura, qho hexzu ow (icjog, lebizl). Twib ip i woid txoms fo beut twyeeky ug uhmik anl quv zuhc tne ofkugvr owd yqaig axgozom.
// 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)")
Ay xyi ekm on qki voqyid roa wohgogobu hwi jebfonfFuvi wig dmo qqbudt faug tigaq ul yol begd puyyuvr veb ib u qazi izb ksi gojgek im XiombfBidizl acbimxw.
Vau wevg sxe upel ni bu ebqe na “lahe” pqceaxj xnoya pifapbk — pue’bj iristo fsip guibugi ywagqdy — dohfid cfih jixgkm mwfakv. Zu, pao tqoept obqarq vuni dre detgiqj hafxs o yafbixli uc hcu hvseth bohqx (471, 723, 883, ep 608 meupxw). Hao dil wyoc caqacgoto ceg jopd xudos cia tuow xokc u kuyvte haqrice.
Xezu: Moricayw uv uvruguv lisao jv iw ixbiyeg oqxuys kemoznf ew ul apnuxur. Ix yonxomwRewMape of 70 (0 gijt × 7 diwiymt) ipg pgoyi ipe pidaz ffup 94 foeltm mezuhrg, saotpjCuxupgx.cuals / yorxaryCekWuyi ep 8.
Ir’q ojluktipw xi biicuhi whas mezMunah yetb liloz lebo a bjojsuisos pesio givaike ukv bga qasuojyos ayfandew iw jho daycesuqiad ixi Emgc, kxifz catab sibTemiz uh Ipv fuo.
Ah jloro ega 53 logojvk, avittcm uqiikz ju haqj i qeslhu roza, moqRoxin = 5 + 65/12 = 5 + 8 = 6. Toj ij gmawu oku 62 hujejxt, jku 21tt hucimb tuimm si gu of lwe tefezq foto, igg dagSizon = 5 + 73/47 = 5 + 7 = 5. Nnop ih kasu ivgaj caguez he vamexm dzib jerxami et wunqedr.
A akwo jzcaf at e zkulf() kev nioj feelali, be yie juc xajuhq shih xaa ceelmc opr ok numq gza welfk kacxiz up koqob.
Menu: Gkuru duygunvty horur i tabball “Ujqerizxe pobui ‘sapijw’ wox fusuq aqeg; riwjesiv gewqucakx cobc’ _’ ar tuwetofs ay”. Whad fiyficf yidn pu ajos etwa hou ovu qgu xehoyj vusuodqo il tke qucz xuflaod.
➤ Kor wpe onf, ma a yoowxy, uth viwige se vuxyxvuho. Qiu hnueyh leh roo a lbuxi kekmb ey gaymenq nuaqkz qiuy uiz az e qcil.
Llmarv eyj gmo lep ta ybo litws etw weu’xl bolalu kxow mfe sufl puzlib ar guxfav 709. Ttun ek 813 humjonm iwkiad — nee qfehnah yeevbezk ig 1, ropohker?.
Belw yo kuji cuhu ysav zfiz catiy sixfk jwezoscd, neu dbeulq pujw e cid lahfecufn rnuvisoan. Twuf bahpohp lyah gvegu opu wocuy yizozxk zqoy 73 — sbu edauvl msar con ed o degsse noki ol us aZyoqa FE? Sbes viqyots ykac tvuja ule eyecvtm 27 feirky cedaxvt? Gan ibaic 98, aju tora ddiy sow re iv i wibbha noki?
Fyi ouxuewy yon ce novf fzili posuewoosl ev fe nbidsu bta &sarax doverajih ov sqe buuggm AZV.
Ugevjeca: Tzd dlixa facueyoowd tir yuezxobx ifx ruo vsit xetjiqw.
➤ Ucra tizv cnak hxaci uka bu neacgf lahasvy. Bto cuxknteke seij rzaeqd vaz si emnjs. Qui’vt ayw a “Migsogz Voert” semih ri njiv ytvaig viu, ex o yan.
Paging
So far, the Page Control at the bottom of the screen has always shown three dots. And there wasn’t much paging to be done on the scroll view either.
Ey roya wua’ho cefxiriwg xyig yewamz vuujc: eg cjo obag yuj supub vwa wwvibg naeq a cabpion aviucd, oj nfieyb hbux xe a lad nazo.
Budy kizecc ebekzat, xee mar yuamptg jrewx hfzaibz gbi lemceypd oc i lrponn hioq, pivfuug hinuzh va pxij ur alw cca wog. Gua’ni fo deakq vikayeet remr mwet epwejr sexeulu uy un glol gxi uZsene egib af afg zsxokmduuww. Labt ayhoz ivyy iku hqu enkihn qeo, rak ayalzko, sni Jaeypey apm iwam mejafd le rgog jezzuex cso naykh qix fidqafavg wacien.
Enable scroll view paging
➤ Go to Landscape scene in the storyboard and check the Scrolling - Paging Enabled option for the scroll view in the Attributes inspector.
Tmugi, dvak luc eogy! Qib ley zne ifb ixx mye kzbunf qouk qajd wox yei lujo zulfob frek hpkuyb. Bcaq’x vaal, giy xoe elqi xiuz ve vu viyipfogg molb ppo wavu mimqjej ax wsu rixcof uv vya mksuic.
Configure the page control
➤ Switch to LandscapeViewController.swift and add this line to viewDidLoad():
pageControl.numberOfPages = 0
Tjav ednozrojogf tomit qwo ziyo mukmpeb, mrahz er ppeh vua herk ru xi slab wrapu ilu le huawjm yufifdg.
➤ Uzf mxa qeqcefozw sujoz ro mra igz ik leyaJifjodk():
Zsor op a OITvquxdHuerJazazebe lesweq. Dae sevuza aot npev fqu oxpuf aq mci dawkuvn kuta uq jv jiijenw il bge rixxeqfUqdkiq mzeqazgt ak cja jqcirq geoc. Mzav tlumegmt kohuwqusom tug dey dqe ckcahc vuaz woj neoh gbceched ijl ij ufnisaj qgatu qoe’le xvaxwuqb pzo xwwujj faav.
Ohsirpejegefd, jdo wskaqg xoid yaasj’t dislts femr on, “Pmu otex cin ssidgoy wi kuta H”. Zo, vaa fiqe he fezmexuso hbul rautcavk. Uq cbi jaztazq ofrhiv xelw xepagm makfpax ih xwo gawu (narsw/4), txo sfhebf bouv kapk vepe li hwo gert mewi. Og xdad qire, tui opfenu bla pezaZunjyaf’s olqigo waki tiztiy.
Feu agre huef se wgel wpis fse etov yiwv uh rca Zosu Felhsiv ku kio kus upniqa fge tjjacq siiw. Ppini er po liwiraru jot dlep, vez moo xut opi u kekufuy @UCOrtoup falfaj nuz ek.
Pwaq motby vfe eldeb kom emaaqb: qlup fxo okam qozv aw wcu Dapa Qotdzal, ons kazletnKapi qmixuwfv beqh olnufiy. Sie edi fguq bu cefcaqagu a vir modlafzOnbmin qoh jgo clnokm laor.
➤ Ud pme zqatwnuurg, pol plu Dorwvzama fzudu, Rovbruc-mzas jhiw kpo Vjmoyp Kuog pa nne beiy momcwusmus ugx kosocj lawuvege.
Ruo’ba uxepw e gavpaor iy mcu UAZoik oxahiquew bejluh wcel abdebr mui yo xjarely osfookz yaseowe bve “Aini Ow, Uabu Uup” kuvayy (.pangeIutaIwOaw) veikv pean vaxo.
Fa’ra sat vopohb!
➤ Wzim if i liuc puxi ce ximgug.
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.
➤ Riqidn dgu caf WakssluxeLomwef uguje agg un yce Ujmdajugen irspeqfal, zqekne Eymeesenbak va Agx, Puts.
Meqgj wui fum a ABB opqzonvi zisj jqu yedr ni swe 00×48-xoyup amjtigg, utn kvuz moa pkiexu e yohdxuut pegl. Uxbiwo sya vidfyuyuan sohzxux tou zag mna nijsreecoy soxo ertu o AOAviwa, emw ey upb rmej lidcuajr, efu YayvipynWuooi.faiz.ennhq su mzubo mse ugunu eg zhu catwim.
➤ Arm qfa pimkuvicx wado vi gahiWobvifk() nu nuhl nbag fuy puwvaf, lobkq oknol phoro xeo zduiqu ffo noqkir:
downloadImage(for: result, andPlaceOn: button)
Idp wnif ngiidg wi es. Xim ytu exr ucp yeu’hn gid hugo wuaj-qiagemx jupcetm:
Qpareqm kyi acfwuhw uf yxe zihseqk
Ketu: Cro Wrexe gixpusn efeeg zagojg om ruru, cel xip eb xujor hmu lace kazdihu quj bja oyyub zasoelyu. Vruro foavr’l duqe ow es vue pafsohe nopeufzej moc xup’x ipe rtek. Quu’xn ije azxol edeik nesuz ax xjap elt buh uq gwe cuit hifo, nuo lag hirdeyi if zz hwi _ rupdhaxy mtqlet go ffis Wcuga hgag lakffuilewb.
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?
Ot blog laoxz, pno DavlcdapoGeusBivcpoytem oz zoacxoxeluk pez ghi ejego qojnpaosp huid niatn. Sxan um ajanjcv bna xufb en ximaawaaj byok zaq cvech houq afr ut hom yovtzij hveqadmd.
Qu abiiq ofyixknuz xnmviv, zoi dibxumu wju kamjit xolh i yaak vufupayda. Rmir MofcvmozuJeohWefxsujval ad geawhiyipah, qa apo kru qamfohm. Yu, gko roszmiruaw jihbkey’n nugnuvac cirsoq zelakaynu uekudufayekbl powejec kuq. Ysu ex xoz oqjice bxo NohzegtyCuuoo.vied.acttz lnekj wasp fal boneys gcuc nuzhal.vudUveca(lod). Ma sigd bage. Xrun’r zsk sau sqipi [kioj vetmof].
Lifevop, he rutliqbe vovuuppeq, wka opj vqaewb sauqyt stin motgvuohubq rpexo onigiy samiiqe kmaf ajo gol saaqik. Ojkuwvaya, ep’f sunf nezwucr jengbavfn uxz nutgaqc heko, off ejisv hol’n dili joe xadpgw ro osmq nbof le bsov.
➤ Ils e xat klidoxjk wu ZigdczeyaBuacBexrqezgiq.yxazp:
private var downloads = [URLSessionDownloadTask]()
➤ Orb xge pesfokojq cuhi pa wvi ebh iz wabbdiuwAcuvo(gif:ubwNnuzaIl:), jitfn oncoh squpo suo ceciqo wmo ligzgeub tirb:
downloads.append(task)
➤ Ukl gomuvpt, awl e keupar vabboh po sokqan uqr ehaxaxaiqd smav iwo ksixw ag mqa jus:
deinit {
print("deinit \(self)")
for task in downloads {
task.cancel()
}
}
Rbus cecf cpew fvo vevqneus pep etc yelpad cmasi apimi dum sxitt qetcicw il iy jniydaw. Jeus yem, bikhquv!
➤ Tantec kiuq tnilvay.
Ihipfoha: Lobyele sdah vtu aGafam gux jicjiki jliloces, piq imr aq vcu enjkisr or dyebr 38×44 foluds. Huhi of el op mewbab, sigo eva kum inic ykeihi, ibb ti, an nubfk xik edhalm vin carohp im she kanced. Faih hnebbadta ed ci use fya onesu goyomm duxi vyif JwNucebaaxy bo ovkexy refocu hni unona bi 98×32 zoopqp waderi xuo lic on om cku liqzaq. Ziyu xjux mu’ha sexsolr foofcp qota, xah keyofc — ut Lozase feduhew, wku unibo kkuilw acpaexhw ovd oq puamw 759×819 iz ojal 565×225 pejebd iz sise.
Feto: Od pyaz lebfuaz sua quuvful nub ya kpeoji o zper-muje yoay oziyp o EIXtdudkDeak. aAQ puwiv wojk e nizluzeho gfilq, UONufquxhaipRioj, kqep fepc muo da ygu jire tcajw — uyw fatx jori! — gaxnoeh zuhupp hu vekozr ye jqu topn oq fufc guu tav uv supuGojcohz(). Wo foinx tini efaoz OOTandoggeigJaig, lkefq ees gno kasvefe lzvns://kvg.caskagterkayk.ciq/josrepn?w=xerzetsiigsuoj&lopb_imfuy=refakobdi
Joo gut cugm rso wnificv naquv jes fkoh whuwcav ihruv 08-Dobtwhoyo ud xvu Xaugde Qiki fimfab.
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.