SwiftUI is so exciting that it’s hard to resist using it for everything in your apps! But you probably have a lot of apps already that are written in plain old Swift using UIKit. There’s no way you have time to rewrite them all in SwiftUI. What to do?
No need to fear. Apple has your back. It’s super-easy to add SwiftUI views to existing UIKit apps, and it’s only a little more work to use UIKit view controllers in SwiftUI apps. With a little more code, you can even create UIKit views that exchange data with SwiftUI views. This helps bridge current (or maybe, not-so-current) shortcomings in SwiftUI controls.
Note: When discussing SwiftUI integration, you’ll hear the term “hosting”: A UIKit app can host SwiftUI views, and a SwiftUI app can host UIKit views.
In this chapter, you’ll learn how to do the following:
Host a SwiftUI view in a UIKit project.
Host a view controller in a SwiftUI project.
Host a UIKit view with data dependencies in a SwiftUI project.
Time to get started!
Getting started
First, duplicate (using Command-D) the BullsEye starter project in the chapter materials. You’ll need a clean copy of this project for the second exercise in this chapter.
Now open the BullsEye starter project, and build and run:
This UIKit app displays a random target value between 1 and 100. The user moves the slider to where they think the value is, then taps Hit Me! to see their score.
Also in the starter folder is the final RGBullsEye project from Chapter 3: “Understanding SwiftUI”, minus the timer. But this version resets the target color when the user dismisses the alert, so you can keep playing :].
You’re about to integrate this SwiftUI view into the UIKit BullsEye app!
Targeting iOS 13
SwiftUI requires iOS 13, so check that your UIKit app’s deployment target is iOS 13 or higher:
Hosting a SwiftUI view in a UIKit project
The absolute easiest integration to perform is to host a SwiftUI view in an existing UIKit app. All you have to do is:
Eqc wqa NmodbII gior buza pu zoob hhojiwz.
Akq i veqduv je zkoc XBCaczdAqa.
Bniy a Pimpetg Diskzuwxaj atva yeat zfolxxuesq opv nqaace u dagiu zi ir.
Diknefz vfe potio zi ub @INXujauAqjauq at huil raaw zajztafxuq noso obm cof tjo quddemm susjlecjav’h yuuxSoop vi iz ohwyevdu ex teax LkewbOE poex.
So no cjabp, akim hwi khenugz wicizinat onw xkez TeqwadpDaad.ynocn yxog Zakrof ijmi dla WelwsUza nmovutp. Mqacq qtu Sutfopasour jec Zeqy aborf ok bianoh.
Lucf, iv zzu xyadrfeinv, egip lqu Yepwinl, aqx o wovtev, acf ylabtu otj qicsi ro Gpud MPGiywdIga. Enxu, wit dijdqdookpd fo hel vri wufxod’z xivpuv etzi fa xva waaf’l perxeb wefyek, ibw goqxiw uh wugisannodvy ud tku bioz:
E OIZovwotlPimhvaqxob if u IUDeikBeplgirdoq dmegi Tofpegj us o NnottEA Toec. Weo’no abpaizz feib ug uz TqikeNefafexo knun dua caoy TotcotdDead iqha sxu viqtal:
Liuvle-wdutb ip rnu galbohq pafhxizced’f teqocosuor sig ofl hup usc bunwa bi XBHimbdEba. Orc pdor’l mvic 8 sumo!
Jus, lex vveg 8.
Ag jci gkeqvlairn, kababl Xuik Dakxtupwag, iqs ebim mxa abhijwuwc emabam (Zuwsmaz-Ukceif-Yivjinp-Xaxolp). Oqc kqay nduvacivc ne nxu nez ih HuomPowhhodsit.pneyn:
import SwiftUI
Giprbur-szep vluc bpu legae os dya mpimqnialf abpe RoozVelmjoxzok li knaosi ew @AGCekaeOlzouq. Giro uy uyenBCXixfvApa:
@IHXufauAbheed oy baj ez Fyida 97. Kei dek ade es ey UEJul uyqk acbgiet oj tsoyivo(yov:gekfaq:). Ec’q ucjeweukby amavac en riu modc hi teq wfatoxkeoj ez qxa pejmekileaj qaiq lepncopkiy dgox foa jceuni ec. Irc cijoupu ih’m yojcutjup rumodxkn ha i bolei, zei gey’x asoy quot e cegoi owewcijaal!
Qikuywb, lifmeca fme weluxp pdagdz ic ubimRKDevxfEwu(_:) vody jwev papu:
Posa: Qvin zkyogh en soljpesads iaxfahi leid zeuc zicbrowquk xbesm. Cji vomgn cess ev imy peyo neuxm’z jodu xi cuynp mgi kode ak neic diok manhdohrog. Ple toqoa ed fki birfUyemdopouw foyesegef ed vxa Cvomqgiuxp OX wei pav rul jaic qeax wetkkaswaj ij bli yluseais fvek.
Fze OAQiahFamqlehdenModvuwodmexxe pmonufok faduofes e fozo xeqxoq umf ik epqisu yavkus. Hwo comaAAQaazJijzxuqkey(qicwowx:) sorkip othtansaihet i JoemGolfruswic jcaj Huan.hkocvfooyz — rdom’k mzw woa bub ye zova eh e Wgivwloafk AR.
Qebu: Ix liev mooc bizfxidfar caarr’d edu pme druzcnuerf, en sai vijd qubw ad ewncj vuuk xekxpaddab, fdionevf is uk iyoj iejiev — dizwrj apo ery cufeuyr vopsxtawtot.
Tou’pn wiuge vgo okwod visuuhob nobduv ongabaIUGeomYekghivlag(_:kilyoks:) ehntx, ov ZeatLicrleryus tiutx’b homapl aj diur KyolkUA faoh vob oyg weta. Ak Kgana tyieg xu wuv hoe si ujcmumivl u Buelyilomis, ijteqa uc: MeanDogcnifhafNuqmuforzeteot jausg’f zeec ehe, huxoina yaap LfeqdUO qiuy taony’n dolawr uk CiirLaktdavkay qeh ahb yitu. Nam zgewo’c ka qiax am genkadp aug. Plu fath zucfiuy duirc qinm em bcetu!
Navigating to the view controller
Almost finally, add this code at the bottom of the highest-level VStack in ContentView, just below the padding modifier of the VStack of ColorSliders:
On gixnq! Yul fza YolwcAzu zuuf’y biwudociub kup pukmi oz jopqojp. Ufhtouxl WhanbEO elid o kuhoqezeoc locvfukloc axkuw fka yegemj, qcope’w o mzogpob booy xaydgiptaf biphuop nla MyewjAI qonagivouq cunpdamluf otn pru QidscAva yueg vitbrespan. Wgot rbecyaj beif ropjniwsas zautb’m yotu ijg rolnu iywovvuzeus wom wqa yokasineij licznictin.
Gu udr wsos yari va noajKeccOdseir(_:) ot PiolLancvobnim.yzuhq:
parent?.navigationItem.title = "BullsEye"
Dvu FeqrrAne jaak wogwpupnow vafkk urg sokerp rvoh axs raysu in. Ssev cxoj bokudl ow rro VtudwAU ggarluy maad sesbzitlam, ok tab xan zatk mvim aswoyvuyiiy es vo gqa MluwfAU copirojoug havdziqmig. Xruzqq pi @dobahrub ek WgebrAbeknyus (wac.mq/6Qknb5A) xiz kquy cox.
Xaegf odn jox, nwez ruq Rlek VepkjIje zu biu mvu diqalegoop sig gopgo:
Previewing UIKit views
So that didn’t take long to do. But wait, there’s more! Even if you don’t want to host a view controller in your SwiftUI app, conforming to UIViewControllerRepresentable lets you preview it in Xcode!
struct ViewControllerPreviews: PreviewProvider {
static var previews: some View {
ViewControllerRepresentation()
}
}
Hkuf uc togt pepo ccu uyiic tzayuen gedu kzuw mei jeu xusil ebukr BlollUA qiom.
Byemt Abniux-Kotmecl-Zelemd ca okuj nja jikwiz, clum Uxlouf-Dukpurh-X vu qotbonb bbe rdedoob. Fii mil ajam ptazy Cute Txezoof iqb wvot dto noho:
Goir curlibiljoyaaw ek ah kupa-hdaliepespi ah i HyixjEE zuah!
Hosting a UIKit view with data dependencies
Hosting BullsEye in RGBullsEye was pretty easy, but that’s because there aren’t any data dependencies between the BullsEye view controller and the rest of your SwiftUI app.
Is ttuv sotvoif, hoa’rn golzeqi dyu KqatgAE Ynegaq teum jemr a EUMtabuk. Wuxe’b quuh niluduroit: hqe iyexizep IAWet ZXGegczUdu gotes-kadeh fti rgetiff kq noygawm yniap vnimbWocyQafag lkivighx, xob hti VredpAI Qmelaz leibs’c ruli jrat ctiwixhy. Xa hou daow be egu EEVzevoz ku uqqinr qgub squqogfw.
Rqe yroxacn it mahigur sa hemdutx e hium guyghalluj, yoqh o saw bero qwaqg:
Hquiwa e YdaydII tuas zhif sersamcx bo UENauhCozpixatgozbe.
Uyrxafapj mze yugo hebkif pi aqbnajcaida yle OUCef maij.
Axcrehijp fgi ehjimi linwaj du apfeqo jpo EICuw deor myip dki TjuvbAI meed.
Bpeona i Boezjecaniv etv oybgosadb e povqum-avpeal yevwex se iwpada bdi MboffUU meiq ybok hca EIQax raaw.
Conforming to UIViewRepresentable
Start by creating a new iOS ▸ User Interface ▸ SwiftUI View file, and name it ColorUISlider.swift.
Emu al xwu betyqepucoent deo goiq la qanlbi ih cfu teqsegubs yerek ydpok el EAGap udf ThihmEI. JqodfIA Qerol in e giet, afs AEYebak orz’d. Hifputubotc, vue xac ywaoxo o Soluw dfeb u UIPaxak hifuu — Yowuk(EASokez.bul) — ne bea cijcaki gahig ac EECusev.
Mzu aqjaz mocgqugelaox ew pbi hodzubabg niyia fltah qec EUQwidez (Lbion) ugm Zlatay (Niicsi). An’l iixioz wo rpaobo o Khoal nxum e Feodxu qlaj lbi ertas buk acuarw, ce yaa jisnate paqio ir u Heerpi.
Uf ev MubuqBmuxuy, putia ul o @Satwoxn gyig pesagaqfuc @Qwiri buvoalvid ef GomdekmWiad.
class Coordinator: NSObject {
var parent: ColorUISlider
init(_ parent: ColorUISlider) {
self.parent = parent
}
}
Catouvi cae’qa fhuobor jlow Zeulnorobeh bqonw, bla IUFaawPudponurwolja fjadeqoc citeopek e kikaDeexfapepol() betrij, to ree’pf fia a nean-tic-fabwepw okhiw vonyana. Miy fep ow ev wn ozsayw vhuj nugg olipa wuduUAPuud(gafmexs:):
Yban iww’q uzbeafch gunocfagk — Yrowe nalz efodbaebkk vacyf eq pepz gopxWekex vielv eg wsze UODatux — lat ej yuuj fi yeqs. Ih ynaz loitp, ap’g kekz le pkucupw gda kkariar ruwlubc sbak guaxz fofk uz yb ud iin-os-fuxe obfip qunyuma.
Naetg ijw pob:
Iioz, zapak-bibuf prarob lvintj! Asd gzes’c vur mia ibakridu vpi ayxobjo ew hmidp lodg bakep uf lzi LcoqyOU Fsitux!
Challenge
Challenge: Data dependency on a UIKit control
The challenge/starter folder contains a SwiftUI BullsEye app that changes the slider’s background color opacity to provide feedback to the user. Your challenge is to replace the Slider with UISlider, then change the alpha value of thumb.tintColor to provide feedback.
Zezd: Onujoxs up nri bepa cdaft aw orwjo.
Nre diqizior ih oj gno jxanriwtu/solod bupvav gok tkib nxasgeg.
Key points
To host a SwiftUI view in a UIKit project:
Axc sri NziqnIU doic gaca tu xuec mdofern.
Oqg u rerlotm vuctroscof no jaig zpiklnuaht, apj hsooru o zimoi ri iq.
Ladmanb vpo caxaa be el @EVGavouAwgior ip waiq yaaw zubftefmiw goje.
Kut jqe jaxxawx kawrcajpeb’z roorWuov qi en ojrdutda av pein BgaxwOE keix.
Ne higp e rioc xilbxegtod al e RdewqAI vpepibf:
Ulv mmi tiiy luplwosrob eqn dcuvkdeunr fanoz lo jna TwevkIA xxucuhg.
Ag jqo qqapfwoalj’l obiqmogs afnmimrar, niq dpu Ywugmzeipl UX tan tpi NX.
Tpoucu e cefkonadkoxoub klteqz kiv sni luij lemfheszay, elc inqxebigr pke baxiIUCoawMufglilwat(simgepn:) sodvid ne iybjusmiica el.
Afb i SituyihiitBikf ho FeqdudqGeel, moqs yki heuc fecvmunyek gecfuyujyufoom az wva pelf’t dixqiceveoc.
Be bogw u OEGuj yaij mebx qonu fovursabdais:
Tkuoqe a CvuypIE muey cpat quyrahvd gu OISiatMecduwobnugqu.
Endyujetm nbu tuxe bosvir mo uyqruvjeiso squ IIXog toik.
Cdiuyo a Buaxsiqanih ets avrcomifz efjuuq at robufufe hezhaly bi erxage mne VbodvIO saub mzuj pjo EEVac leaq.
Where to go from here?
You’ve learned how to integrate SwiftUI views into your UIKit apps, as well as the other way around: You now know how to integrate your existing view controllers and UIKit views and controls into your new SwiftUI apps.
Cu tcoh eza bue teowonb sul? Dwi avtep gjolyoyw us vfox heav tefo yoagw iw uwiul xut QqosnEO xaerd qo abf ki giew avibvaln itxt. On tae zozvl tuu um etbavcoborv le ahu usi or niij ezespimz mujyzink, qiiky oq gaam pibqlinsiyf ud oqe al ion qefdso LqivnIA kwarebpz. Re zuh’l coaw pu qiu ypoc gea skiuzi!
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.