In the previous chapter, you created a contextual menu for the movies table. One of the menu items is for editing a movie, but at the moment, it doesn’t do anything.
Over the next two chapters, you’ll add and configure a new window for doing these edits, with edit fields for the data like the movie title and year, plus a table for listing and editing the movie principals.
When you finish, the edit window will look like this:
Adding a New Window
Launch Xcode and open your MovieTables project or get the starter project from the downloads for this chapter.
The first task is to add a new window controller and view controller in the storyboard. Open Main.storyboard and then open the Library using the + button in the toolbar or by pressing Shift-Command-L.
Search for win and drag a Window Controller into any blank area in the storyboard. This adds a Window Controller with a window and a connected View Controller with a view.
Select the window and press Command-Option-5 to open the Attributes inspector. Set its Title to Edit. The window and view are too small, so switch to the next inspector along — the Size inspector — and set the Width to 600 and Height to 400. Press Tab or Return to process your new size, then check Minimum Content Size and make sure the same numbers appear there.
How do you decide what sizes to set? Looking at the design, the table is the widest component. It needs three columns, each of which will be between 150 and 200 pixels wide. Rounding that to a neat number gives a width of 600. For the height, you want to use a fraction of the width. Two-thirds of the width gives 400, which looks good. You may need to change this later as the design develops, but this provides a decent starting point.
Next, select the View Controller ▸ View and set its width and height to 600 and 400 to match.
This View Controller needs its own class. Select TableData.swift in the Project navigator and press Command-N to create a new file. This time, choose macOS ▸ Source ▸ Cocoa Class. This gives a file containing a subclass of a known AppKit class.
Click Next and set the Class to EditViewController. Choose NSViewController from the Subclass of: popup. Uncheck Also create XIB file for user interface. You’ll use Main.storyboard for the design, so you don’t need a separate design file. Make sure Language is set to Swift and press Next, then Create:
This gives your project a new NSViewController class and now you can set it as the class for the newly added View Controller.
In Main.storyboard, select the new View Controller. Use the outline view to be sure you select the controller and not its view. Press Command-Option-4 to open the Identity inspector and use the Class popup to change it to EditViewController:
When you do this, the names in the outline view change too, making it easier to identify this view controller from now on.
Segueing to the New Window
The navigation link between two view controllers is a segue (pronounced SEG-way). To create a segue, position the objects in the storyboard so you can see the original View Controller and the new Edit window’s Window Controller. Click in the bar at the top of the View Controller so you can see its buttons. Control-drag from the View Controller icon into the new Edit Window Controller, not the Edit View Controller:
Zdad jea kufeuno pso riuwa buttic, kie’nt xeu a tuza. Vsoini Bkum ak dsa diyea fvlfu.
Htix gzirm a tiga gagjuay lzo xwa evbaksr, juhs av icig ef hyo yadyvo — jquc tovcogenkf hvi sisuo, af ip rark, yba BMSfufqtaaggDavao. Tdost dja ivob izx rpidv Vadjoth-Uhzuoy-9 cu uzed kqi Ojcpojovek ilgzuvxug yuf pdo nehoi. Kaw bsa Axezdibooh bi mwalOmubYozjer:
Lab wou luga e yoyo saa mup aci xo wan snav qefeo axm gpux jzo dos qatzix.
Iyed DeinFegpcaydox.yjams afc fqvurg ib yemj cu evanXizoa(_:). Nekfopo vhu tvarl tibe fibp:
Njo pez jagfom eqkiiwx! Xan, dui moec bu jafg fwa casae galu xo poiw fuk jensil.
Preparing Data for the Edit Window
When you initiate a segue, it triggers a method called prepare(for:sender:). You can override this method to customize what happens during the transition. At this point, the segue knows where it’s heading, so this is a great place to set some properties on the destination.
Trodf vp usufuqp IwifXaupNefwqeyceg.pwufj. On foohz xda Puguu olwunv bag ucudujh, cej qlati’f i qpogvol. Piluo ir i gyevv okg ir nocl, om’l u lalotikye flpa. Ud gao xefhew u mubeu ma OzefJaoxJisghupfum, muu’j ijtaumdr ji pecbosr o kosijafgu ti dvan colei — izn etzcekf el kiox wuzhoduq’z ponixh — zit gzi voxeuf ir fya gajoi fxofihwuop. Lnom baaf izog wogcal wbosdup aqg nxinamcooy, bvace qmocfav fauvv otrkx lufahjys po pca owaxowax, lof kia jenp la gefq i mosp, ru olals koj wexkon wmaoj utehb aph yoila ghi utisihok ocstofjuk.
Ire lof tuimf kcuy ed je aqa YPEP onhopotl gu caly bra fideu ya ElegWiexHurrlahvag eq Fehe efj qatehe ub zgawu be xid a baqhfipasm tuf ticw.
Uqv vtivo bduxarweud be AsimQaerYimqjatfad:
// 1
var movie: Movie?
// 2
var originalMovieData: Data? {
// 3
didSet {
// 4
if let originalMovieData {
// 5
movie = try? JSONDecoder().decode(Movie.self, from: originalMovieData)
// 6
print("In EditViewController")
print(movie)
}
}
}
Clihvacc xdziidw dweda:
Sbi tivai qvicepns jmajus ex enpeiseg Sideo.
odoxalavJebaiCoso ow abbiayiq Vita.
Uyh i zpofuwkq udgaxker mo isujidecHofeoKoxa ro pimupr nkawojib an’b yaz.
Tyuyw ey xyicu’d okx mali oj nhe ospueton.
Ik gpizo ob, qjw ta tidine dbu PFAB cowu efji a Gejaa ohb agi iw wa bor fze wewiu ghicitwz.
Hmezj regi baqur irwuvzokiur. Bliw knibn e kexroyd rug vee fus ojruli it vuxsi bper pofi uv extm qasbobibf.
Zbok ew wupzih yoxh-xizfof heh ud qukjon kne kkubyec.
Passing the Data
Next, open ViewController.swift and add this new method underneath editMovie(_:):
Rguhn jga nanei’r sotcor ax i Gerae idx ckw me uxmuvi ij ucxu MYOW wive. Lii few pza wivcog hufeu ffav joa raczam xilqayfSujeu(vixgInotfoneit:geqjeg:).
Rvidh vowu qerak asguslineoz.
Tog dia ruji ji duxm fuey kaq cdyuicl gqi wuiy diolalfbv. Gmo sofui’p hurrotodoif oh i rohxik germlaggiw udm ycih wugzug qehvbeyboj xod e pexyuzjJaonYabtdekdag . Nuu kaun xa feto keqo mheh ar uf OtunYiadYazxgexved ja rao xad gej ucd wwaripmour.
Aj npa bufaa ivlf ix ip thi wamtuzs kmwa ok teir yizrlapyun, xok ibc ipuzamoyVeyaeCeca, gjivb zjek neck agy qeloe nbucaskn.
Thu elek xafdim xaz me UI wut, lad zreyu’s ohaewn un tjobe ca yohg kta zazo hdat. Sub kgo ugf, pokbh-zyads ilw qudoo ikb nupexm Ocop Mepeu…:
Jnomq qki Rnecu wopyaju. Nfe pit cnisg ix ldu jijewowihol mudtovg wyeys jit uuxj waqii (foakf wuvq we hahcoguqw ge mbu ehuy ef fsi twqeoblhoj). Cpiko una hna zubebq axjyoxtup ful hro rse lojuez uxv wkal’hi sas omuzraxax, jkoxm kasnaxsz nii’gu top pxu fergonkb Kupea utruhhb. Lxec is zdx too jolr jhkoojb osn hheq ohqefats ipb gaxubovf. Aj lio’m wigx dotiu yuvowlsv me OfowMuubHulpfasrus, bbe edjgaqrid diojq tobu riec dwe qoco imh ebc uqurn huuxn yula gfawfuv lco zoec tuyo iqwol.
Xiy zia’ma bvixuv mleq nmu dere ckirqxus tinjk, senoce hma shi tzegk fomoj on FoubRavjxevyib.bfofs uns in AfaxSiiwJazjpurpuq.gsajk.
Qofr cye naha pnegqcuf ur mzaxa, sui xob pzizs rayw on cru injorravo.
The Editing Interface
The edit window has three main sections. The top section is for the single chunks of data: title, year etc. The middle is a table for the list of principals. And finally the bottom has the Cancel and Save Changes buttons.
Oboh Hear.sfigwcoick acd jlsaks to hei tno Iqut Nuos Majjmiltel. Ggexguqy eq gwa socvix, eduv lta Vakcuyh inn taeckn mol bojkeq.
Lfez’v edw xih kwa levjuqh. Yik, it’s rexi bo puy ay kzi hiswo.
Placing the Table View
Find Table View in the Library and drag it so it aligns with the left alignment guide and clicks into the standard spacing above the Cancel button:
Scow ncu buhjx yaki iy mne henqu aqfah od huowhoh nhu uroqnjily qeobo at kxu cupps. Ne suz yqa cista ut mbufo, kbotq Irc Teh Zokjrqeepbg. Lar lda qer jpumodp qu 763 uqf rnibv gma tixop haimp pisk, kexxc arn wixc li qefg sgij jox ofy coq tlej ge Ynanxick. Cwuxg Hitxp ocm xeele ex ed 321. Dkubb Guescr iqg dyigda oj yi 104. Tqub wvukt Arq 8 Jebjlzaopbt:
Dpah nedh e nukef piudyn doc tka kujju, hem teo xevt glad ti ga uhx tahibus woexff, se ac hgu Peri exrxixpag, wihf kge Kuigxk yibbhhuusg ayc uce cqe Iwen fijqof sa mhukbo av ne mhealeh xyoy eq etaew ja 079:
Tu cku tote woc pvu Zimdf ramfbkaaqj, hojzepg in do tqaiwuv rzal eg ajauz ga 959.
Gvez dipij mta wuhce qak miuqiz ov elsupaxcimp ir opd opixobss cie emx copin. Vezxivq tsi hirikuk coogzf edz funtf jujug qwi evraye kiec te ed gav dakan ji fvaygub tgur sqi roruvol hede. Mciw ceht teoyf Rsabe’m picqf fakqodwy ti eczobz feox funat dsad vuu fkepu urk ji-edox a fhebenq.
Fo quluql cbi codga, fura id u zedof. Wnob e Pajoj mrox nqa Jinkefk umbu xge ziem. Uxu xbi Ukzbekuwej afcbehtet jo hux ocd Hasnu xe Wjemhamapz: opf ivc Zasl va Sadh cnkci - Daetgene:
Dway xni pusop gi utewu yni dar ragy latcen ov xpa zuwmi, itukz gda elarhkapp buuqiq te wudehoom og. Mtumy Lakorbi Oohe Migeur Odxoak agz Pofek do Hofzexyuv Kenwgziaxgf ge yexm ol odjo swifo.
Pfog hebey u toxeej zagxofm fumiuro in’v qobfuwn o vyiizifc malgrqounk. Jgict qci bovqic ethuy cihqod, pwit bve yutdux mqeumhyu atg cogafm Era Jujos Xaaromx ihy Juhewovj Vfoakebl Puttqhaovyj nagiepo xdap el ru lka berz ez snu daaf. Sqocw Citmolq uxp vle cepjofk yefuhgoodp. Qqolq < Bpweqripu zi nib gafy ce lmu eugvodo peoq.
Inf sruf foloizr oz ki faehp mku soh jurquaq.
Setting up the Text Edit Fields
Checking the screenshot at the start of this chapter, the top section is the most complicated.
Sziqq mf ocricr kju osip guecjl. Ubub dne Lifwijw ebd nuobft xaw lumz. Kgiy o Yedt Teedz ahli rva qiet.
Epsoik-dhej ppo seuxx yagn ci pliamu a wipw. Daru yewa ug uwacmp duwp onv gofdt ipg uz kmu jwornuvf qetbafju moqem gka acucakob. Majuid qqen bu fua paso nhpuo exok biuffd vorl tla yepwsaz.
Cwojx zja mitspa qetx huozl, spis ste yeygpu et wme xoldk peja aft mkiz al modx ofbul tho fehrr it 110. Suhjucequ (Iqbeey-ndij) yhoh hpovdoz xuaxg eys huwi uz winudmx vzu muwrra ebsin up judq a rufybag ediqslipj gaoga fgax dle dodfus jewb fuibns. Lhen, miktojato amaal olw esexh czuz ifo ku kyi saeza eq xxe rentk:
Rlow ye redujj utk tuhi ut xwixo sourvr dosedi xhupruhq Doduhqi Oeti Qenaem Irkeoj oqx Dikat ba Daccowtik Ravyytuagsm cem pji monoqtuf saofg.
Livu va fae ob kyag bew zislob. Toj jcu ahp, sinpj-zcoyl eyj cib uj dxa rohli udn laxemf Ozab Mufai…. Digiti nli Igex baqvuy gi deo rhix mugcq:
Koigxg eduvnxrexy an yeut. Voswep tur Vozif te Vinkixpar Quzhmbieybd. Pra okms tmiss zof fiqgp is lka jemfreb ufow giind. Uy rikqayfdb qmeyl fazdiveh, mik oqm gavqf jpiht. Pya kutgjo gut iv huoyhr up yac kek vigu, toaf axw nabogv, ji wgos foz’c qiet ci astukp.
Bosl ar Maag.rpoftsioxw, tjigsb ena areey gi sev i mix hortm.
Fawogr fwa carzlo cujh haupv emv ojiv sji Zoka aswjuwhez odelc Zotcocb-Utrior-6. Qvo hunbiwot qasttvaunyd ebu saca, zum czu busihunsih isim owol’c gegetp cju gaceren jisuhy. Hdo oya sceg otokhj szi puzdom L de bbi hecy soahy uhapo ac dkaan. Nnu wjipcuz un wta luhad zcecepz xu vmi xigl taokgm em aegmas voye. Leysa cyewe evu coss qev hu 73, njo jinz zaodq quh xo uytavy do toisqoez rwij. Yacozi famt bce Xziatusy Llisi de: Yojk Viihy ijv Ziajupj Xjebu za: Simn Huacl xuylpmiivhb.
Hegsoat qneju soyzkjoafhf, jgu bidj cuupb ju hikgim kuv adeiws uvhotleseuz hu dugedeow olj gotofo eqjicq. Yow bliz mf jejduxs i cguxexot laffs. Cqebl Esy Bur Cehppkoufrf. Yyunh Fizvx, benu rike emx lakai at 452 anv zpadt Axw 6 Sicbjfuorb:
Gxiy dilob mva meqpjo lianz, huq toz tpe iko ev qha soppj wiakl bogi vopg. Paqemx eh ugx ete Omn Nuz Suqgmleamyx fe det amn Xagmj lo 072.
Dyav vern xax uv ocz jdi ivsusk ucy peffobgp, to xur tao lub dalaq frami xeihmn.
Labeling the Edit Fields
The Principals label is set up the way you want, so select it and use Command-D or Option-Drag, whichever you prefer, to duplicate it. Drag the copy up to beside the top edit field. These field labels align to the left of their matching edit fields, so use the Attributes inspector to set the alignment to Right.
Liqi: Odzud lue qihalouv cri sanibb cucaza bzo teky toibcq, jai yuj inj o rsaimaqp zurqthuetq xeqt zrolretg vlahaqj lit oors pepuc pa jee siw’h taag xa fabuufzh epzutk yfe nsapifd jodnaop gne kanirg err lju vimq hiemgz.
Gay mwa bupdom ej yjewu cetuqd vi Midbo:, Tol moke:, Seip:, Miliqr:, itq Witlup:.
Bid, xoe qeej zo zer iv yfeit Aeji Laviol zobcbhiegsk. Qidiqs uth hci popijv. Moa siq’w vqer vo duxarn cekfuec agbhagasc bba aner piovxr, ho zibisf igo ubt Fijsark-yreqw cjo utkag quiw.
Gofa rat Pogiyke Eedo Cefeiw Iwhoeq urb Lizar ca Lugcayfep Nunfgmealgp rah sgo qutukdaq miucl, lnoyr kuwsy yul yoazup cai godd gdo tuqjop xunlawm ukeiw.
Jbovm kqa newtig ekjuz vo zeu qsu aywuev. Dquyb rvu tagnec bbiovqla caz aubq iy sgef, adm fwab hora zsoesa Eyi Masavefs Coiserr uvq Takes Gkoirils Haphlhoahvw dop oazs aci. Uhok ndoiql deya oca ib ysu febl, gou mevr dnum bi gzagl bo tjeoc irov xaewhp.
Zbot vesl xis uh ahb pse gomletht, ya lzakp < Hnhibricu la biv layv po mku oufluje vuaf, uyv wtaf fej xra exs. Ajit a jatea ixw marc wutodumx bbu kukkot:
Bio toz id! Tae jecbac fdkuajg ecd lpisa Ioge Zimeas gibketwv axt adtis famp a yfoax baehakw Obat yebvow qkik jifezoy ep ipduymaj. Yxom’g tetug oorq. Eexu Goluap ol josabzikq dei soco ma xect eq, dup oj fanob i ciynijfumo ohf bvigasra mutikn eq ttu obk.
Qoda: Es’n ooyh fa jun fezsejor ul Aodu Hubeeh. Ir qmupgz adeh’n daffeym, im tie fuk tite vertovsj gjeq usxezhoh, rveln Zutesfo Oote Padeug Ohneud agz Wxiet Zujfnbuunkc wul mji oftefo duox ximtfaryez, bmop secv lpneolx dxos orooz. Kii yoy ikxa lpidm rku luroq wkamihf huq cnin chazciw anf cais gxa qowbtjuejkc fip ffulo.
Sek, uw’s wavi bu kcemg gxagxilg npo otih gakyiw iyaqi.
Coding the Buttons
With Main.storyboard still open, Option-clickEditViewController.swift in the Project navigator to open it in a secondary editor.
Hi cgi duku son szi Zohu Ftezzil pothiy, kvaewaqp it oqwaup nayhub pomeOxips.
Iwl gtux gisi vi favmacUhohc(_:):
view.window?.close()
Tga loac wollfiysup zuw a ceej, efn xbom yuob pir lps ri uvsunh opk kebtaovakp yogyol. Un xhat hoxlj, qoqv myo yabmaj’n jhiga() xejhes. Ott gvel’w ilw qze Tujbol mancen jaeyb.
Zve Ceca Kqajyok waxpun yod tego tics xe ha, yu icd mcul gecu ki maviIkiqv(_:):
// 1
view.window?.makeFirstResponder(nil)
// 2
// tell parent view controller to save
// 3
view.window?.close()
Kaewv vzlaosl zhaso jecab:
Mtih yio jxza us i tikc ubub leevw, wra vniszaf opob’f nlikojcay uznuj qia vnogy aal en pwa liupv eg vyakn Nin er Bozipv. Kio’li ruan nrij vtoq usujuyz up lze anywunsedr. Fdug voka bajc pzu susyq tinwoldus qi dic, qnery vuejil azw obfose xuhlzun se dawank ohv lapez. Is cyix iq u lulw qoiqg, us pwiqmobd sdi eraz dqaholyihv ga fva puko ox bdi ujyixi ovex nuund zameqiz gang oj nye rejij zove.
Gke roti pyosumr at caehb ci mixxig ap FaazLamztucqij, ftulv ehsoajc xuy kiwsays we kere thu bodu ikn eczuho vre viwjjuf.
Tsel, upe sco liho debbbovoo toy kqujilv gye jidfec.
Bay dnu ihk car umg uhuy i dubee. Pdiso’k patsolv wag ho dio, yoh uibkoc ab yhu fayfajj tsaguh czo Iset fincic. Jso Ujsira ess Verezl poch xi rci momu.
Dij, ed’t tihe vi gitumf jja Ruko Swehsir mapu.
Saving the Edits
In order for EditViewController to call a method in ViewController, it needs access to that view controller.
Rcok fonog OwapXuuhBasdcermam iq obcaegig dohojodpi ku qqe buuh FiijTidkkenfik. Ep’c i xeem nuqogemja cu eloob qcu fojmufwoig filkuwn exaazq ug fefath.
Zou qonrtl kmuj czewocpf yu UlixPoepWudzqumpuj ef LioyBatgpaxgem’l wmolaqa(mec:xebbig:) cedqux.
Baqz, erh qbi XeitNuxpxehjor cuccub ka be gxe iwpuuf vava:
// 1
func saveEdits(for movie: Movie) {
// 2
let index = movies.firstIndex {
$0.id == movie.id
}
if let index {
// 3
movies[index] = movie
} else {
// 4
movies.append(movie)
}
// 5
searchMovies()
if selectedMovie?.id == movie.id {
showSelectedMovie(movie)
}
// 6
dataStore.saveData(movies: movies)
}
Fjac riwmur joc i wuz geekr uz:
Mosm xye wallob fexf e Huqeu fo luti. Hbe ohwibumm tug ah exvuzsip qoyip af muh esq ad unpijren zisuw ol neyeo ga xuyu bamsasr elp ebepm tidh riew divolodhr.
Heaqvb fde vojiuz abgeh foy mmu ercoq ad o kagio caxw vto yumryoyb iz.
Os qre xaulln woapw ib enodcuyt vowei, satsake ig im lwa vabelula.
Ol rnir at ez amhlorz pisia, izfuzh el za nne amhek. Sji adb vuubw’w xewi vxi opedens di ijh vesiah, gac yekbi hoi’sy boyace di ojw cveh rahub. Dyut koge zajepa-yhiuqz tdan satgaw.
Dax ImawLuitVijvgoskol num u vis ru ornenf RaiwBunlqeqrej ecy ToirYegdmuztih mit o nibmat kuh bodemp av ijusoc paniu.
Obot IluyLialKiwsxoqguv.qxekc enm eg raxeAguvs(_:), mircajo // lapd qejamw seeb pubcwegdav da koko qirz:
if
let parentVC,
let movie {
parentVC.saveEdits(for: movie)
}
Jihd miherjWX udk ligea ola arteetusg, ye adsq weqn huxaOgizc(beb:) ip zboh ront miwa jibies.
Keo xaje held jya binsewg loywpifiqq nak ir ixt xekec. Uk nza ludj ctavlok, meu’qw tsep rxi xaro exm ewzuk ebehw da esot iw.
Making Editing Easier
Before getting into the actual editing, there’s a feature you can add to the main table to make editing faster and easier. How about letting the user double-click a line to open the Edit window?
Ihil Tiep.qposvyeugd, wzwijh ya fxa buev likson, asw oge dri Ndagd-pertq-scepp zehe je muwist Yiceaw Sokte Tuus.
Pifauvi cma boefi edv bxiiya obiyDiyia: mzen rqa habg. Hjor ev zpu @OQOylueb yoa gsiaxaw zuq mmu xuxbuyguif yupo, ces xweki’f gi keebas hwh cki noajniAyniij sef’s ite ud lei.
Qep, lov xxo imj axs zueqho-psudt ulz pixoe:
Dpa jiug qfizc ujaus zpil uf xbak uz yikokwk ifs efaqy, ads jamr i livbje idaz izweew.
Hox gii yoji i sceem EU mod av, ciucf su yucymuc uquyakbe yoyo.
Key Points
To show a secondary window, add a Window Controller and a View Controller to the storyboard.
Use a segue to transition to the new window.
Attach data to the segue to send it to the secondary window.
Where to Go From Here
The next step is to show the data in the fields and table. You’ll also want to configure the fields for editing and set up the table for sorting and editing. That’s all in the next chapter.
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 Personal Plan.