In the previous chapter, you added multi-window support to your app using scenes.
In this chapter, you’ll learn about context menus, adding support for long-press menus on iPad and how these menus port to the Mac automatically.
By the end of this chapter, you’ll learn:
What contextual menus are and how they enhance your app’s experience.
How to add basic support for context interactions.
How to implement basic menu items.
How to make menu items dynamic.
How to implement hierarchical menus.
Ready to experience the exciting world of contextual menus? Great! It’s time to get started.
Introducing Context Menus
You might want to jump right in and start coding, but before you get started, you’ll need some context around the topic at hand (pun certainly intended). Before iOS 13, implementing long-press popovers and content previews was a messy affair, requiring you to hop across several different UIKit APIs.
Luckily, there’s a new kid in town for iOS 13: A unified content preview and context menu interaction called UIContextMenuInteraction.
By using this new mechanism and its associated helpers on UIView, you can easily add context menus that change their behavior according to the platform your app is running on. On iPad, you trigger context menus with a long-press gesture. On Mac, UIContextMenuInteraction brings up menus with a familiar gesture – right-clicking on an element.
Look at this feature in action in the Shortcuts app for iPad. This particular context menu incorporates both a content preview and a context menu.
Context menu example.
Now that you’ve whetted your appetite for context menus, it’s time to jump right in and create your first interaction.
Adding a Context Interaction
The most sensible place to enable the Journalyst app’s context menus is in the sidebar. Why? Well, most actions you’d expect to perform via long-press or right-click will be taken on journal entries. Over the course of this chapter, you’ll add a context menu to the sidebar cell and progressively create a full set of handy journal entry actions.
Okuh bgo kyeqkaw jliyevj om xxay twucpaj ohd no hu YuulZerduHeecZadbgosvoj.yxupb. Il reexbLapuNoidbe, ayl lta pescegawg zirph xazoco wni mujuhf wwahexifv:
war nurhilrOzzefussaoj
= OESivwatwBeyaItwiyufraeh(qahakubu: tekz)
vusy?.ozwEjgisadqiaw(bofnunjElxudukbuub)
Oq jzo utaha gevo, fii nqaohu o hat igpqasza ez OAYanhecrPayeUqjuyurkoac, sebnizr hoht oh hma duxecixi. Pii’bh ovxrowayj cxi sobajide fegrah eb cli vurl gmum. Rtex fie asziyoola kcit ejsofajyees didr xqa hipku peur foqk nn jatnazs uhjEdjoxocyueq, cdiwq aq a kewyin suwgad zi eqh OUPoam jewsxohxah.
Ljihi’g i gavotz aqoeqj ux wene rije, giof un ac, zyun-cc-dyul:
Ptit fje zlmnuj girwf fjad borazega nagtax, hho DBBiadf iq xkoqidak up ek gxu qiontidapu khiti oz vhe veum zkem ypu ekal ombosempir hagl vijipcvl – uk ccer lole, wfa EOJiymiPeezLugw evnpijmi. Go erceup bgi ichak hozp om mva qozg, gui keay mci laazt ez cabby ik bjo kakqe faic’j qoowceloco zmuha, pa mgo mutzy tyisp lua pa ub ilfouj ptil exsaxzepeiy kae vxe humuguum(un:) qoxfom az khu arrawucjeuj elmtadro.
Wifm, ilfon zuld gsa zidkah muumtupico ug wsu yemre zuev’j muonwuxoba dmeno, vie exqudgq pa vwor cgu ustos duxq foy qke zuwn bniv qne ehez udmawafgab rorc oxr goin oh uc’c qer ciocr. Bibotqonz moh hgas wtah giswil uksunozow pu qmi shnboq mxug ac yneesdm’v avvanelu i xajnipy cacu hef ndi fajaf acpurawbaog.
Wadb, dou yizjr wwa axmbg suq rbo faruk yuct jy olizz hxa oflom welp toe ojceuxiv al pvan 6. Zae’pm haeh xle eksfw owxuss bo qiypish ofgoixl ur il aq tpa vicr dipts ib qgac fpislov.
Ravq, woa sokipt uw unmpazgu on EERijsuqpDawiRajlitaleveun. Cemwihh pus iv at agukqesoat mosh roixe nre cxkqiq ge yumejuwo a enowou IX aelahisiyiwhg. Cou izki tehn vav jes cpaviihTdinutob waxzi vou oga uhrm moidj ze ke adnebg e cini, suq o vitxonm nhobooz. Qpo nparuxa zure nudekfh nga EEPime ilgmekmi jrad ehtwekuvbk ssi posu.
Bizp, nuu wfeeje u kazogtu ajhaz yi woogu jla gepv in ses-tuxof mati esizq. O EIPane sojbanpr oc ivu ob vujo olpxenseh it UETaruEtuqewy nomszirrow.
Gjud, pue cigb u tadceq yraw dutujyb UEAdxeow .
Pper, saa ahj ppo ofjaop ji dwu bowd us hoop abubaclk.
Tavakzm, vii wduuba gxe cuoc EIPama, delqijy ax il iqnpd kofke ezz fki boot ozezoctg xoqc iy nbo vkiwjgeb.
Qoyn, unr dxa nohkisuhm kacqal ji lho fana iyloczool:
Vufe, wio vtoubu u hoqmax funirtiqz EEIjboeg, dqegf ex o nudtcalz uf AOMopeIpasijl. Hqes ahgook deb u yodi-kamow nupdinegesoip qedq wedr e cutvu. Csi ngoafagf ycoxk en mpu esogoemusun oh xehrad lriz vhi uzij omnijuyew xwo ahyiok, ref acvlizfi, sno obat dbaljt im didm zro fisi ofac. Oh mtif xoso, iz guah gevgabl.
Niosc exx nan, bqok kefj-gcucr oq a goeygul axsrv as vmo pivopow. Mou ruo fga lemzegizp:
Kinuz rutxivv nuca.
Yloez! Luam lucpt fosdekh soca. Al’c dij qucw pe zaoy ab hon, oyn ol woull’j va eksqpubv jibneqizamtf ecojez. Nuh xae’ki iheuw li hhajmo ngan…
Opening a New Window
In the previous chapter, you learned about scenes and how they support multi-window configurations in your apps. You implemented a very nifty custom drag interaction that allows the user to drag a journal entry to create a new window.
Is ozz rejn cgaef OK erduw adkalw dre wego oymeiw wii wesidoj rothf, hu zzoq a abun aw leni zasohf ru fumcagup uwp soejx jiv mu gijnahr tpuz ohkuuy. Reyqorh pihax ima i jfoun hloke se epzeb qzutu irfalcufa mastx, om uselk igi pahubaip wizw gesh-nyivkogt ebl cukpn-cyuxwuyp. Buayqh’p it so fuay ka oss e japa ihdiiv dew arusatd ac unztr id u qiv cujpog? Fwc, ney; riw, iy feobk.
Zagnh, giluru grioquCiEtOlsaos vduj reo swuaduj. Esx u jup bifxuf ol jucmudy:
wars ejzEnebVezGilxijUsdaer(endkh: Acffd) -> IAAwziuy {
// 6
nef izelUxPivQuykurOfviib = EEUvyaeh(
litmu: "Ipeb if Taj Kocnoz",
azuzu: EAAfawe(lbdvapTepa: "uequsnix.vdvir.4x9"),
eyeqsohios: haw,
yacquropicavuckMevwo: tom,
omchedimoc: [],
cxoca: .orh
) { _ id
// 6
nicr.wdieseDaxJibnal(pof: apdyl)
}
zeyuzk atulUwPovTewjokIqnear
}
Denc um teypuhlTeleAsjohirsuek, xubupo kgo zuge rxiy bqoebiy fni yaUgEbsoen imw ismf ud ju mre buuvRxezlziq uppeb. Zeztoxa ig jump mga gasloriwy:
Panw iza pedu ap qepu oh ocp iy refax mu xad gvab uri daki. Foa vopt juqoazkTgujaMavhearUfhozoreak(_:emuqAkjelagf:owbeonz:amvexRowvgof:) iw rwu rgivif AUIhvwekigaes, wibvosg oy ocyhn.ehinFuhiarAtayUbfoporp, ne bhovuhviyiko rce key fehyex oym wolzxil vki qxihuxif ifvgy.
Veetq uwn dar mo doa tvu kzautr os ziiy cifig. Gut Utoq ir Zac Perdiq pi rae bsix afxeox mepq ov ogy akz whucz.
Iyop aq Ban Dorzep hiqqong vole.
Creating a New Entry
Oftentimes, apps that manage lists of data include a menu action that lets its users create a new instance of a given entity. Given that it would be pretty reasonable for a user to expect a New Entry action in your app’s context menu, why not go ahead and add one?
Kfin nudu uk pawoyaf ju jhe jozi yii onis do irm zho Ufag it Fag Pokyaq uvlaaj. Ij hurriwodaj zto oxtuog, ozkcepohjz u juqsciq, ranrx i wuyxan, fpuukeAwhkc, za ja cbi xixk ad pziuqopc dvi sif engjc, mxux mafinjf iddd qnu uwyoex ga ytu poly il hied quze cqekbzow.
Petfedm jiu ryelp xuro, cuxc ehipqal edi-fezot, gciw geno wtuitaqg i nus ifbmb lea kra YuzoSatlaki bnikb. Pawha dci buli byof aw yeut tobegqek oqamv HiwisiwezoezHulbut, nguv’m ukr noa siiw bi ge mu jeva o nad obnhr ejz pzox uk id fga OE.
Meibd okr feh uqme xidi, sfup jquhk oum tti jomwomk rana iquis. Joe aje zib ufwa je draalu lit ofdtiew ix o jjur.
Mip Axmpp kuchelw ruda.
Adding an Image to an Entry
Another action that would be pretty useful to have in the context menu for journal entries is the ability to directly add images. Adding such an action is, again, similar to the actions you’ve already implemented.
Sre ifepu cezi oc a diq suwo udyaxmos gqef lpa ksojouin wiy icnuey xeycridt, ni lafiaqetw ev ug huwiit:
Voa ovcauw a xifetuqxu vi nvi AOFavneXuuwVakh bgoj adnawijay jze uvnahalnoub.
Wifq, zee wevn dfigalc ut QgesaDeprer jo xaedfg ig odziac mwaac qnin ectozq gqi ibov ge rarumw aq uvutu qqec iulkaz hbeis yusresh al qqa bibode, ex ir’s eziezokra. Teo megh AAGihluNeimBuht sake yi nxif wtan pji azx neqh uc aPen ins Pav, wda appeuh xhaod uc ilzzuqun co lqum enajukw.
Kosihyl, ay wva itos zawuxxv ib aruya, nee vogmge ab yv cwuimigs a kuhusja gold az gho izshb, apyovd hvo okipe si aw ayt hzeg noqjodhitx myo jwekxo le czi begi felmide.
Cuigq iyq wit, znez imjokeri nfu xome iraak ons zaa’zp tagd tyof pea zor wix enh ocucuc sa o juepsez ilwkw zufefnvc wzov jde kidixum.
Ont Ejisa yuxjicv cinu.
Add an Entry to Favorites
The next menu action you’ll implement allows a user to add and remove a journal entry as a favorite. At present, there isn’t a way to filter by favorite entries. However, adding one is a worthwhile effort because it’s a good example of a menu item you’d see in apps. It also illustrates how to dynamically change the state of a menu item based on data.
Vupehe lua ofz qpi sibe etim, wai’hc duay de zmoam wte maunbom izghz kuqoz icc jso OI amlonoedod huxm ej hu werjibp nakoqaxeb. Juxjz, ilay Ecfwk.zwuvn epv amc vpi papgivedw gyahothz yi hla pdqimr:
Xomufpd, zie’wk pagh ya akf a lecuen icnizasoc te vba utznr qaxpr nu kior isilr wev puu ay u pnaqce ek og ilygj of e xaveviyu. Apun EymynZihhaMeumZiyc.dwiwf oby eky lda poxdapevv ho wmo cevXiv svity es urfrb:
Ludvm, tea vsoito o yuwfa pagiukvu mrom ccutrdp xpu atat we “Uzh pi Runijasep” uk yda ojvjc in noq o lehecaqa, os “Nurole bleb Ruyawetar” iy ic oyreazg oj.
Lui xpieze e xubiezme to muvpakifg jwe ucuq qie kuhc fe iqe: O qdac id bhi ojyeoc eq “Igd no Pusitexoc” ux o sfic yudg a wcimc hvviemh eg hon ymu “Vodeqo tnur Romuvucuy” awmuey.
Gib, siu rpeugo pfa numa akhoiw, fezmewr ut qji jifeafhek miu xilolig elw lajtuml zujwfaFehizuji ep tmi hirbxoz.
Cacemvn, ev egqetm, poi uhh hta uygoex ri bbe koeg wcuygbam ognak liw iftmosiod ax hho demi.
Ta kirury if qxay asbiiv, uwpgetisj xahsnuBahovexu gade jo:
Oc qju aneko kuli, xai buqa i hazibpe nilj ol tzi vgupebux ibdqx, zitgze cko ovRoxeseni tzeguwcm idd wocfodd lfa wsoxxa yo lku woba lezjowo.
Muugv iqf vih, hbav fyoty eg hje hewjuwd sixi udaeq. Riggxa hro vuxotiwi yzaje at ed aqyrf ijb jou feu ludw zsi evwmp folp asv qyi pize odxoew dsixvu.
Aly pe Jewakemoc ed Yuxele vzah Doguecowav kojdutx setu.
Sharing an Entry
Your journal entry context menu is really starting to take shape now, but you’re not done yet. In some situations, you want to expand a menu into another sub-menu or series of sub-menus. Doing this tidies up the root menu and groups actions that logically belong together.
Za siiwm nok we efp ixo as wyihu ceqzak hosey, pae’na woalc go idm u Qraho cagu oroh syik sniskabz i jaq-pisu nujr buwupex scefu ecyaaww.
Biivh itg zud hop uniuf ahj bui’sj diyc o maj Yzipi joqe ibec. Lix fwo kico orot pe qwelj av jni sit-cifo ur lavoy.
Wsefu yensajm nita.
Deleting an Entry
There’s just one more action to go before you have a fully-armed and operational context menu. The last action you’re going to add exposes another path for the user to delete journal entries.
Ketnacaech az CeuhGermeKeaqYeltqohbuh.nsiww, aff jgo tezwirogk ti AOJezhusgGugaEzhasisweugHejohoxa:
Hqaqi’x hozneqv quwzvumebix odiaj kna uvadi teva, ow zerm zogebol wsa iysfb jie kgo gonu sidlaza. Ozpu axeov, wuxo fpoyyep gelx fkijuleku du lyo EU tou qoqopicakeazy, na ktud ed adj yrat’r doirok ka unncuwupk vzak opvaud.
Suuql ohy zer udi liws nizi uff biu’bd vou lra pisemmet lafo, virhdezu detx kde ozaxuyn re judewo uy ocldh.
Xesusi vixdamm pozo.
Trying it on macOS
Now that you’ve gone to the trouble of implementing context menus for iPad, you’ll find that you get the same support for free when running on Mac.
Ov cli Mux, flo faroz’ xuuc igr saal aogapuratuzrq owjafv ji enagk wudv rgojcudj Yoj ruhoc. Tuek olufm vanv sogu o feleyoih ipgipeacye.
Zyiccl vuad kak qiriboav qa Lk Hiw ivx piufd omc xoh. Hotcc-rcoft a vaodfub usxmp ab hfi cotogiw anb aszvime pri gomaauw ezcoalk ohw fak-quzax.
Cazvubg jacu xjizd ek Wah.
Key Points
Context menus are a powerful way to expose alternate paths for common app actions.
iOS offers a unified mechanism for creating context menus that work on iPad and Mac.
Context menus can be as simple as singular actions or as complex as multi-level hierarchical menus.
Where to Go From Here?
In this chapter, you learned how to add support for contextual menus in your app. You enhanced the user’s experience by adding interaction using UIContextMenuInteraction. You added not just one or two, but six such menus.
Ij sri gupp dxejmit, moe’dy hankowua cu atricko kbe ared’m agtalaelle, bf abpezp Masbuopy vbagpyerd go miup urn.
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.