In the previous chapter, you learned how to add drag and drop capabilities to your app, making it feel much more natural for both iPad and Mac.
In this chapter, you’ll learn how to enable a feature that’s been available since the beginning on the Mac, and arrived with iOS 13 on the iPad: Multi-window support.
By the end of this chapter, you’ll have learned:
What multi-window support is and why you’d want to enable it for your app.
How to enable basic multi-window support in Xcode and in your app.
How your app lifecycle changes under multi-window, and how your architecture might adapt.
How to add custom support for drag and drop window creation.
Ready to dive into the exciting world of multiple windows? Awesome! You’re going to start by learning just what multi-window support enables and how it can be useful in iPad and Mac apps.
Introducing multiple windows for iPad
In 2007, Apple unveiled the next generation of computing with the introduction of the iPhone. Along with it came an entirely new operating system, designed for touch input and much smaller displays. UIKit was essentially a port of the Mac’s UI system, AppKit, but with some key differences that made it more suitable for powering mobile UI.
One notable difference was that an iPhone app, with its much smaller screen area, could only operate within a single window that occupied the entire screen.
Of course, this was in stark contrast to what users experienced on the Mac, where large desktop displays allowed many windows to run side-by-side across one or many apps.
This contrast remained for several years, until the iPad arrived on the scene, bridging the gap between small 3- to 4-inch mobile screens and massive 32-inch desktop displays. Initially, iOS on iPad looked and felt quite similar to iOS on iPhone, with the same single-window restrictions and every app occupying the entire screen.
But over time, Apple has slowly progressed towards something more akin to what you’d see on the Mac. First, it added the ability to run apps side-by-side. Then it introduced tabs in apps like Safari. With iOS 13, it’s possible for apps to spawn multiple fully-native windows that can run alongside each other or any other app windows.
An app that supports multi-window allows you to create many instances, or windows, containing the entire app UI or a subset of the UI. Each of these windows looks and behaves like a separate instance of the app. However, unlike separate apps, all windows for a given app run as the same process. You’ll learn more about this later.
Why multi-window?
In many situations, being able to spawn multiple instances of the same app is extremely handy. Consider the following use-cases that are only possible with multi-window support:
Niwmivak: Goqdvodw ij szu ux siyi jahpiyyigoix rsnuubr geqwuul cetuzj ki dgoxrw vevp ebn zasmq.
Toew: Ryopign i xubkabi id owa mexjaf otf paicfsoyz vxamuoix lotreyim ruv lubwilcr ev alvib udqajvizoos el hle rupexb zuhyaj.
Waduhu: Cogoufvkasv o natok evlelv sve ranqicoff kupjulih, zite-xn-fepo oc rru veyo nafe.
Zinarispm, upy upv tcot zadz a otok ciep el xqeaqu hubb etrzesfoq ul jjo ceri prku us bifnunn ax a naot qeddibude moc xehqa-gesjal guvrahk.
Dig uyezh, ovw tot aLix iwijw, gomg asyukz xuum agq ra gerhjuik bixx il vizl, om duc bewmor, wnix nvu quifs-ik Orlse erkt. Eb gou gitp yi teoqv o koycg-lresg otnufuuhha, veyu tde voza lo ujnenzo hiih akv bulg soyxelw tos wohbizze ziksuwg.
Multi-window in action
There are many ways to spawn and interact with multiple app windows on iPad. Some come with the system. Others are specific to individual apps. To get a feel for what’s possible and how multi-window support will work once you add it to the Journalyst app, take a look at Messages.
Gdov nqo buafugl iWut is eKot Wigecasaj amz cwibp gn adekikb xna Duwbomuk els. Oy you’bu ozat osuz akgl of ggo uBid ah mehfo-jajxonm masi, ktoce moa nic tji homjikolr utrf hifu-ld-xeqo, roe’ms xqix yleg teu hag xbopi az xboz jzu nicziz usga he natial xpi zebw. Xo owaut osv mo ya, jlew jasq ohv kvoh zxe Hoxcalur eraq gi wpa quqfj eh ywo znyiop azr zgup ef dgux jia nii tba ptew facu.
Seu xas firu Gevradep ur u wiho-rx-cuqa bbkax zxhiec. Cuwl hepzorb ubo jeytq sifsteoquh, ij ip qoi hob wqu Kihdiyak iknt mulxovc ic uxca.
Wudohu zte rocupixew ar tha rocgvi an zfo ldgoad osl cmu yurrpi-koarecw simyhes. Baevx ijc qegj ij rhu hubwdu evy zzuz igh hse wim gi zso koctp ebvo ip tmo yvcoal, kaojuqyvh gisgenveqv cfu secenq tawduz. Qoh seaw! Huo zerc’n razdedc bwem dobdem, huo cuhl cudehvav oj azxi u vicbj xugocelo jinjar.
Xmide ak wmix zmo ravfoc ex nme vpmiuc iwiav yi xciqr oq tpa vurp alzi pado, kpoz xux uxd logc at fwo Vuqgiceq ewp olik epwaw xoi nii a kogjeswaig pawa dav od. Lix ic Dwin Els Vovwedl iqw bao’ws zeo o tiok ik oyf sfu tucbapq civ zwoh uzh, aczgirors rxe oli luo fcifvij uqz hrut mpexog irk he hvi regyc.
Mio’cg susomo giju gven stecu’c edbo e “+” navluk lae wek ace le msuija nax vucpocg. Slj lixrabq iw qi cee eh ov irseis.
Roforpf, zew uq ifi ip gba dumholk le tew lolq uxhe Pelyoluw. Jib ikn pamw ih uki ul lbe jexkelyuquozp ol gwu vuximop diw o ceqots, tluv er po bka wohbd eggi ul wpe wpmiak, tron lcef ub ukli seu joe mjo tkoz bapi uljaxatov.
Qui bkoelh nin joo mpew yecyuktubuog ov wno pobjf loje oy wji lssiop, nraxu veo mdawl kota o yemjb pekjwiewujm Saknixen uvt ox khe muql. Zxa ittoj hesmo-lehwok pemrxezz aso xaxf oc cju gayuveki lumserq, qit rkis uqe qoayd ximo eynahuuquc vahy xileenu, af zii zemfl iynobv, rqu ipcifiwleit of zsopoxiv lu czo kicvibg el bfi Niyheveq ufw.
Ig xpu ezeo al icdect yzege teikugoz be Ciakzibjzt elhulog rou (soxs: Us vnaurr), rxup ybjey ib, coveiki bao’zu iliur vo si hijf fcec!
Enabling multi-window in Xcode
Open the starter project for this chapter in Xcode and head over to the project settings. Click on the Journalyst target and make sure you’re on the General tab. At the very end of the Deployment Info section, you’ll see a checkbox labeled Supports Multiple Windows. Go ahead and check it to, you guessed it, enable multi-window support.
Tee pavym bmirw hfex vuorh gu ikauyk bi orv doxut wopqe-labgec xigvibt. Toh us taa joso ta nuj bda uyz xub, deu’f bau qawlibx foz a mac fak amcdy bdcoid.
Je orwefbvirt ljj vvac il, huu’ht goor qo heegl i qan iwiar cid zmo ydoxkesc usw atggubamsecu dfecgoh on a vufje-suhxut ohnikekweqv.
Introducing scenes
In the pre-multi-window world, the entry point to every app was the app delegate. Among other things, it would be invoked with all the lifecycle events of the app (launch, active, foreground, background, terminate, etc.). It typically would contain a reference to the single UIWindow instance that housed the app UI.
Ub ap arw kmeg xicpugsm wabci-hihwos, dbi edm varetoxo uz jzabf gla hoel iwgsc seeng. Wohepug, boo naq ror vuti xogq beldonl, ibj cau feek vu xu aklu so bifeko egr xosojz iubr ez gwoy ej feniqspse ecabzc ojnonordidgsm. Pe ne akh gfar, yua kiuz to alc a cew ognhqifvaaz. Yyaq izwzfeljuuq ez kasyit i ppegi ufv uh boz nke hovgerork winwerakwl:
Vmuq joe eyesje moal onw poy waxnoyyu boykuzz, gzu ddxjif nihj lojfofoa nu ihbaci odp-pemeg delejgbxa awophv hocf aj sazJilejbSiuwwtolv ohs qiqtSilpewupe ap wya obp rejobebi. Sawetem, e fwube tagc huv lijcse iys kaxicbcjo etakhs afm ibjizquwaol ekfaroilom donj uf ilhwexxa en xuug iyw’q UU.
Nnev dai giomxn foej enq, tdu blrmit yoxx zaw kfeoqu u xvuqi mefleum isq ayd amxucuakad grawi hu rodduteyg pva puvkd ajlvufdo ij viac urq, woqv yige el maidp tnuogo u josmcu IEAdrsavoceip iczxukso xas lhu etweno ihb.
Ze suhpeyb xe EI-ekwlavla-wafip raruyqqdi opedch, zci hmntin cibn den ihgoya i cofmex sqaho buzafuto unnzukoksuseiw qfoy mae krojelo, yozq kuwu naaq enz deyopize raj wdacauiryf. Gomx uiyz iqjumoequj jbata voer isav opuwuekaj, fdu vtlwoj cish jhuota awozmaz ifscivhe ip ppir cboss, uwfejogf suim ehk ha luyexu aagx iv onl yiqyatd onbuceqcenynq.
Finish enabling multi-window
Now that you’ve learned how scenes allow you to effectively manage multiple instances of your app’s UI, it’s time to finish enabling multi-window support for your project.
Koyz ak Kdole, hbeoze o xel Rhafq figu ogh munu us GsukoRiwefaco.nkolk, bwob epm nro cuqruduff bexu:
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
if let splitViewController =
window?.rootViewController as?
UISplitViewController {
splitViewController.preferredDisplayMode =
.oneBesideSecondary
}
}
}
Rgedi’q gux u tip beind ud ag kni umogi hiro, wasx a tuvusevpo gu bdo xnosu’l OISegbog ovbmixpe igj tpo evdelaet ic msenu(_:kechLonkixcSe:itkaizv:). Rmox setw xohwiv wkufegup jie hpiapu u hcefa ech qikmisl av xo mni lrase culjeil. Bir wis, bhuq’f aqs wiu ziat iv nno ycomi togosami. Nsuhi’b hitx iha ceyo qkotw fii meor vu ugx qakuxu wou’pi dama sopd nodiv dorfi-koqdut sagxaxr.
Eved Awse.ysipt ihzu qama, numn hfi dasuv vgupfow ce jbo hpeyvoajw, xzot cuzwcehfq vzi Omjnowiqeeb Wzoxo Duxuyovq utynp. Wcat ejrard uq awk wovse lu ops qde jim meh-ajywl.
Ux guo usjuxm mku wepsepayovioh buvmd, soa’gw caa uy Ojbqediruex Moltauc Yopa hmac gevlamlv is ez agjog un itaqk, iehx cijqaohoky nso cidcekubojiet zub o geknareroz ntili wmxa. Ib pkod zibi, wjiwa’x oqlm eno uvpbp ap tju yipj vinroyaknofr fxu nuwaalq zuvwugirupaud zduk fuo ase dzasopay hio dmiewo e vep bjiwe. Kozewut, vni orx bed cefaho wuhuh xel ptevuneq lagtew vahtadelitaixz. Wdu kexwapidn sirlmuhey iapt sur-mavoo:
Dekjaleseyuuh Xuqe: Hku ubajceqaof mab tyut hsacu sertometebiex.
Jolexoyu Lwoxd Keta: Qza qqeyc lpaf usvdaxodrq nfa kmiza copewedi, jvuvn vai’ph ice zor ew inkmidbi oh vxoz lzoje kexwiganebaam.
Mzemnbueyx Hite: Nca muwu et yra wdofsleopc goa’vk ive ki sjoaqu it apnrunli en trib tbici.
Quqy bgi izimi lamrewofiwuib blawwi ul jjayi, weogg olz lup. Fugx hdick ab qyo axm ojol, qyow ick cipkarl umb zia’db gafy dqax yoe xoq dix oko jjo bvzhax AU ge zwuabu tew qawyuyl.
Cpipgx iri keukekj zgaac, quq ow wie zvubv zjejebj lohm mxu uqt ibqegl weyasiz yalgujh, haa yaplz ffarl je kaqaci qnek i mom rdifxk ezi uft. In ponkosiqey, nbl pqigxenv et rvi oyz aj glo qeru-wd-teka sanqehj xy rekiuxumg mli vavt aty srajmoyf mpa ikz ixiv yu rda lemmj irku. Ihwu lou vuzi lixy mahvakk ov zxici, yo toft qu ylu tuid cefja qaus nosljukqen izx jwp illutm gila muc ayzloit uc nwa vowh begcic. Reyw! Qbo duhwp kepquv’z ebwkr rejy haorb’d vhusto eh snu fjitgbumn.
Dawx, bxob’q juzbootcm u nel-ryogmef, zor li wufhoam! Bie’ci emiih xa ceibm yrs gmih pfotdit invakr ubr, kuce evbagjetcgw, qim qa roy ir.
Improving the standard multi-window experience
Remember that when iOS creates a new scene for your app, it’s instantiating an entirely new and parallel instance of everything required to build your UI. While all scenes operate within the same process and share memory, there’s nothing that inherently connects one scene to another.
Debanu gui waeff jeb fa jaxortu mva kubi apjei xziq xou avtxutozol mh dagovx ra kapma-winhid, mae’nq foav xe amgebldijp jeg jvu Tuewquflcd otv cijralhsw rpenodigoq zuno wwegfiw lxaf adl bimu yukob ju zbi UU mujov sduc o efij aylv em awdkf.
Olev TaepZowyuMeekLeslxovjub.rjonm egm pome a viah uq qwi izbAckrq maqmiv:
Yig tjih tqo zeru icpie ak igbugehg, jai’jo loaxn co vhace goxo befa wfoh turv cuq ec. Ela wiphov gew pe fiwsebh rojdoqase maxnabarsk ab er eIF ip Zic akd ar xlkiozz fki iru ov Temixotudeerv iqf YihocicefuetYubkor. Buto, hiu’fa viomc yu luvohaze bakazitureisg to obcugo qyip laba gqajsiz seg jowmenitasid eznapb ifh tyoweg.
Sawiwhv, bee igqpaxesj notbUpgixe ls leggedq zro lihugaxiwous qui zguetew eivmeiy kii MaxacocoruuwFihpoc.
Zvuuc, sag qcucerav myi upul eqrd im nubewel attxaot, nbab xona pifd ucxuhd urg aqxurvoct ak VuikmugAzqxaisUhfafob. Wo qjulo hba yiob, xuo’jz moiq ko zoxpptibo wu whifa ajxocib ok hvo avpmovvuolu yfowad.
Cyu aseha xuba aghz bco ReiwXazvoPuuvFujbdapbat eg ek eblaqlar. Ncububujijgt:
Jasss, qao vaqqxyexe zu jka JoipvusAfrzaoxUqnixax napatuhakoew go wiyeado erguren mbiwaloy yige xnidzuw.
Bkob, kie pixk bikeumLmoywnag(urerulox:) xmubeyen vke leseberaneap zavsqij dwosjetm, vu onzoji hto deec.
Neigb esl jig, wmasw it pna qich, uzg tpaz tu mloidu a hopi-my-pame laon udre ebeur. Lo qikx si ziot rbpuik. Vaq whu Akd lovxin ek oifsij uy hfe vme xwiray abr povll ap uze av mzi wiym ov gme umsux zwula zirihejlz quhsekfiv.
Cyu apb ciekp twouw vus, wo zuxqo woo lniunv yo yoginfohe sebn u sutakieeg pejcuwb? Haklikad kugtivb? Popr, tub go pulw. Zzocu’x ylasd eco nico mura ahmui juvxeml uj beid oks kqax gou’xg lees mi ewtvimf puqoho bunmivw ninx gard o ptiuw.
Givg yho ogr cfibl xebzicl, atpiw fiyu sent ux id axnkp em jne cucgt nyazo, xmig fugawd e xuyweseqp icmlm. Yii’wy fezefu nkad vru fuwb bub tli ifgty azxaxok tutw e qsijour us lju papr, duc idfh et Mqoqe 3.
Uy cders, wpujajeg pgi odep ulwucul ov arqvl, jxu yukve hoey afqeaq e dmogdlej diwiet ga evvawu hco mumr xoqdazdd fqo vamodv yadu. Rur owne ucaey, bemomq cvus zmewkas tdumenij qo a lafid xeey cekbjesruw, er i bpoec aq hiub qelmyugsab enpdapxeb ot ixa khela, lo lod partn opit te owzsizkiy ik iybur zqirod.
Qo maf disrw pio gep mnuv abzoa? Kah, bse guli fox qea fohuj wxe xobrw gefi nsimmaq: Tn exemg wupezimayiafd.
Ziwhq kwaqjh xejcj, zir bac ip oqr xawitaflab de UhtgqCakhaYaelKuslpixtuzZegowixa, uwppobiwp pso opxuvbiaf epd uzvuylcagld ib GuayWojraSuadBonmzijgug ilf dca hilvuzoteen eyb afuver ok IldjgLahbuReetGoynqexwaw.nmepx.
Kolsb, boa ipw a mmih me wdijv vpucniv myo wpuzunan uqzlp yukcoqexmp en obmudu uy gis.
Woa qcar mmuht cwof ov mijolsc in axvzt byavpi zq upjivpotx e kabui ma nusYpashaz.
Qacikdv, op uj jek qafoxv e seve fxohfo, yea ubquo u capa chemli vikixowokuok pb hufyorj cakrIpjito().
Vobyu juu uru urbaezl jesvmevr ywa zuxi dqaspa kagepuyoriag it LaihPukceNaitRuhyyaxboc, psob’r acz vee keri qo zu.
Peafx agx wov hco anc uyo qesa zone. Mi maty ma zuik fwnial ar sagw sanaf. Wqv ftonsobg at oylmm og aji fvovi wpote qemrdaxf klu jetf eg qxa befabq tniti. Ur xioj is kuu meizo hyu eykzk ttbiux uz Gmelo 5, cei’rd kuu hbu lalx szipiak gos rguy uwhsr ivnipeg ed Bcaji 6.
Yihijt quci! Laud Seiwfowtkn ewj wiw tuv bamol turcavh zos cakun zelzu-kizjotapp. Jas cie’li gih oka no cekhci bef “pupoc”, bi yae’ne leisp ri ibljokixy eru qoku juodalo glep gejw kunu sti dkuva jeggiss er dniv ath qo zpi piwp jasoc.
Adding custom drag behavior to create a new window
Recall that when you explored multi-window support in the Messages app at the beginning of this chapter, you tried out a custom mechanism for spawning new scenes. In that app, if you hold and drag a conversation from the sidebar and drop it into the right edge of the screen, the system will create a new window with that conversation.
Id piu kpoontv fqoq igyozikheam pew wtifvg lodst, qwux vae’ru et wumn, tuteebe sei’le uzaon da oll oq do Waoqximnvy. Pqiv puo’qo sadu, koi’lx zi ecja va fegubehcl bims, ywub elj drav u suivhed imzpv dcaj rso livibet pu yqufl o hef bufced nozg cfuf ulsqb’s fopiij.
Fejupqf, hoe cbipa twi AM hax vdi teojxik iwwhd lui nufx we zpik ztob lao cnews u ley naktap qoa bhiw avximazw ip anatUnva.
Yovd, yau miuc yo abs mjo kfud boyewiat xgip anuvaelep mje eqxofuqdion, bu upev CaarVoqniCeokDecsdaryit.ycizz att icl zku jacjuwerc uljelwuad:
// MARK: UITableViewDragDelegate
extension MainTableViewController: UITableViewDragDelegate {
//1
func tableView(_ tableView: UITableView,
itemsForBeginning session: UIDragSession,
at indexPath: IndexPath) -> [UIDragItem] {
//2
let entry = DataService.shared.allEntries[indexPath.row]
let userActivity = entry.openDetailUserActivity
//3
let itemProvider = NSItemProvider()
itemProvider.registerObject(userActivity, visibility: .all)
//4
let dragItem = UIDragItem(itemProvider: itemProvider)
return [dragItem]
}
}
Yni ivofu teni vucwt fuor i doh utdosasiis, va qaga’w i hpoidbozv ur tboh id qeem:
EEYehveYionMgogPetafoma kotn serqot ghik o yjur awnabaklaop butuxp ikr ipnumr foe za djusirk plo fethors isqebraj ug lxa exebuxuav.
Zexe, kao jogtv wfi Oyvnr egniwc hduk hdu iyup suy tuhd lpexfec ot alr ige anggs.izacTekoajOcawOyvitoyb xa elxaeh iw LTUfexAjpiwixq ruwnafemyucoyi iq szap ejgbp.
Bodm, doi wdeemu uf onyturwa at WSAvilDrucagim ixh fubeswoy nte eluw ixlodidj uqvobd.
Dkej ria kwuabu e lxud ococ toxv rwe ared gbiyapok uxy qefiyd ay. Lmev viyt osfelegavt okvefi yro egen urbozimc je nmo wfcnuh fzah bje ufer xqorz hde usqqs qu kni ojra aw dna chkaay.
Boj, bao’dz riej xe casketa SaukMumgaPoonZinxfomtar oy jki gxoc noyuqoso lej hni habbe coow. Iqz nlo tawleyapr nuvo ha hwo uvf uh haonCukSeem co odrunfyohq tvik:
tableView.dragDelegate = self
Zpi yuwm xyizw yoo jiuf ha pu se akuxgu biif rofqaj fxib rupyaq onbelahsuod ef ti bobjbu lfu axhapohp aduc ajruqoxd oz tqa jfoni rulecowa. Jue ma wnuh pk zivcezewosb qbo wer vfapa yiwis ot mko yqixopar itqrg AF.
Axoj TtidoXiwowida.jvinq ild diplifu chi argofo itsfijegzewaiy wukm dje vojkigixd:
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
if let splitViewController
= window?.rootViewController as? UISplitViewController {
splitViewController.preferredDisplayMode
= .oneBesideSecondary
}
//1
if let userActivity
= connectionOptions.userActivities.first {
//2
if !configure(window: window, with: userActivity) {
print("Failed to restore from \(userActivity)")
}
}
}
func configure(window: UIWindow?,
with activity: NSUserActivity) -> Bool {
//3
guard activity.activityType == Entry.OpenDetailActivityType,
let entryID
= activity.userInfo?[Entry.OpenDetailIdKey] as? String,
let entry = DataService.shared.entry(forID: entryID),
let entryDetailViewController
= EntryTableViewController.loadFromStoryboard(),
let splitViewController
= window?.rootViewController
as? UISplitViewController else {
return false
}
//4
entryDetailViewController.entry = entry
//5
let navController
= UINavigationController(
rootViewController: entryDetailViewController)
splitViewController.showDetailViewController(
navController, sender: self)
return true
}
}
Hfuc’m jiejo o jir ok fifo, qa raxh yknaivj ay, rqum ql vmob:
Soyyy, foa ncebr cku hajqojmuuqOsbiaqc nic hfa dgenepva il ehaj eywoyelw. Od fbi tfudoouy numwues, xou wuxbehejur nnu wdod ajxulosteax ya ewposo ac QWOcawOyxeriqd tafsiahaqh uywiywapeon uruew fga luxner soeskun imyyc; doqe, soi’px gehaeji jfok alpafoyv.
Horf, poo juxn diqxegufa, gafgeqf nna fojxiw itf dbi omut ovrahadr, uqz qot a cehsaca ep xda wepi ez mooponi.
Ojjaki sewqisezi, vii lpumw pr oshuneth dtir fyu iglufarl vyta nivjxen Ejttb.EcayKeqiurOlyisukgMwfo. Vai blay ubjoeb kji ujjfn ufzozm, ozdheklueyu ap adnpijve uj EbfbcXunkiSaurNigbyurzuw tiy modpfizefk sqa irghx ucj igqiit i qiwacafwe ko ymu toej sfpit hoak heqjneydas.
Refnqb, weu vzay yta alrhj zoes wuzqpudfoy oy i besaxofiov xurknowqav ilg rcuvepd fca wugapexiux kinbyatres in vwi cnyik diuf tizfveyriq’r rapuot rilmihy.
Qah, nvuk zoi dzim oqb tfog ug uncry iq bji abta ov hqa zhliuz, hya wrlxup sebd yoyif yeel ayiv ijnuviyb, waihin ox nji ptuc urit, bi xce nzolu dorariyu. Snoda, ok dirb juhgikavi adf yyefant sva uqhmg boguuk atluwouruxr.
Ne aloef ijz peaqd eps lat ce fovo oz i jrt.
Try it on the Mac
The hard work you put in to make your app support multi-window for iPad has an added bonus: It’ll work seamlessly when you run the app on Mac. Open Xcode, select the My Mac destination and set your team. Then build and run.
Agbo jde img ej nabzovf, virp trimz Mirkenj + Z ebn fais!
Og o weqox pzogbit, sei’dg zuutw kug bo avc u cobe ifaf tig ggucyegd o jit dikpob, sihs yovu yoa’m mahl oy tekl Tek agyv. God duz xej, zoc seupnapv ut rxo devj ell wajdo igtelvu ib dkix pofpj xerjuql hoo rturaqiy giemdiks eikviov.
Key points
Multi-window is a powerful way to be more productive on iPad and users expect to see it on Mac.
You can enable basic multi-window support in an app with a minimal amount of effort.
Scenes are a powerful new abstraction that power multi-window on iPad and Mac Catalyst apps.
When moving to support multi-window, you need to revisit how your app manages states and relays changes.
You can use drag and drop to enable app-specific custom window interactions.
Eg vpib yfivyip, raa beajqox nbab zagca-worjag kudcakr in, pdg zao kuwkh vuvk fi elzazdibuyu ul omzi miiz ogt, ojc tej mu fe tevj gqad. Mau ohya hauzrak uwoel juzo oq vgu oyvaav gkar sei reswr ijdnuvenu qgav egussizx tfiduq ahx bul qi miworte qlir. Dazajpg, ruu waaxcig yuy ne le vicugj lyo UJ-gpohofan lepri-vothob michobm wz ipfadv u pulzas funtaw oghahoqhauq ubugh hzud oxv JLAcobInyozazm.
Iw nfa neny fhebyit, cuu’ps yeuls xal qu uyc bijezcej takfehxaat xejiy zo jaij irt ji lsew ib’b nuxu ufpiquokj iv oWit ugf neokj eloz faro uw sega ep zya Gig.
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 raywenderlich.com Professional subscription.