Now that you’ve accomplished the first task of putting a button on the screen and making it show an alert, you’ll simply go down the task list and tick off the other items.
You don’t really have to complete the to-do list in any particular order, but some things make sense to do before others. For example, you can’t read the position of the slider if you don’t have a slider yet.
So let’s add the rest of the controls — the slider, as well as some additional buttons and on-screen text — and turn this app into a real game!
When you’ve finished this chapter, the app will look like this:
The game screen with standard SwiftUI controls
Hey, wait a minute… that doesn’t look nearly as pretty as the game I promised you! The difference is that these are the standard controls. This is what they look like straight out of the box.
You’ve probably seen this look before, because it’s perfectly suitable for a lot of regular apps, especially apps that people use for work. However, the default look is a little boring for a game. That’s why you’ll put some special sauce on top later, to spiff things up.
In this chapter, you’ll cover the following:
Portrait vs. landscape: Switch your app to landscape mode.
Adding the other views: Add the rest of the controls necessary to complete the user interface of your app.
Solving the mystery of the stuck slider: At this point, the slider can’t be moved. Since moving the slider is key part of the game, we need to solve this mystery.
Data types: An introduction to some of the different kinds of data that Swift can work with.
Making the slider less annoyingly precise: We don’t need the slider to report its position with six-decimal precision, but to the nearest whole number.
Key points: A quick review of what you learned in this chapter.
Portrait vs. landscape
Notice that in the previous screenshot, the aspect ratio — the ratio of width to height — of the app has changed. The iPhone’s been rotated to its side and the screen is wider but less tall. This is called landscape orientation.
Many types of apps — for example, browsers, email and map apps — work in landscape mode in addition to the regular “upright” portrait orientation. Viewing an app in landscape often makes for easier reading, and the wider screen allows for a bigger keyboard and easier typing.
There are also a good number of apps that work only in landscape orientation. Many of these are games, since having a screen that is wider than it is tall works for a variety of games, including Bullseye.
Right now, the app works in both portrait and landscape orientations. New projects based on Xcode’s templates, including the one you’re working on, do this by default.
➤ Build and run the app. If you’ve been following the steps in this book up to this point, it should look like this in the simulator:
The app so far, in portrait orientation
The simulator defaults to portrait orientation, right side up, since this is the usual way people hold their phones. You can simulate the action of turning your phone to its side — or even upside down — in a couple of different ways:
You can change the simulator’s orientation by opening its Hardware menu and using the Rotate Left and Rotate Right options in that menu to rotate the simulator 90 degrees left or right.
You can also use keyboard shortcuts. Press the Command and Left Arrow keys simultaneously to rotate the simulator 90 degrees left. Pressing the Command and Right Arrow keys simultaneously rotates it 90 degrees right.
You can select the Orientation option in the Hardware menu, which gives you the option of selecting an orientation by name: Portrait, Landscape Right (the landscape orientation that comes from starting in the portrait orientation and turning the device 90 degrees right), Portrait Upside Down and Landscape Left (the landscape orientation that comes from starting in the portrait orientation and turning the device 90 degrees left).
➤ While in the simulator, press the Command and Left Arrow keys simultaneously. You should see this:
The app so far, in landscape orientation
One of the advantages that SwiftUI has over the old way of building iOS user interfaces — UIKit — is that it adjusts automatically to changes in orientation without requiring much work from the programmer. SwiftUI lets you simply define the various layouts for the user interface, and it ensures that they’re drawn properly, regardless of screen size and orientation. Later in this book, you’ll write apps with UIKit, and you’ll find yourself doing the work that SwiftUI did for you.
Converting the app to landscape
The Bullseye game works best in landscape orientation, since landscape allows for the widest slider possible. So next, you’ll change the app so that it displays its view only in landscape. You can do this by setting the configuration option that tells iOS what orientations your app supports.
➤ Wieyl ubf sum qki odt. Ceo’kd bio vtew mu fuzlov fseth set dua voweni bjo qiqokahif, jli ivv oztiss wfitp al kudbddule ocoegwojoib:
Zge amp, bit ya xokvysaca ihbk, sisl rmu xiyevufoh aj vopnpoiv iveugjezouq
Adding the other views
You’re going to see the word “view” a lot in this book, so take a moment to quickly go over what “view” means. This is another one of those cases where it’s better to show you first, and then tell you afterward.
Zile av vxo heacp uto eybijefda; heu’cd tiewq kopa izeoc tgik raex.
A ruor az ocqjdahh wgov xejr njecp aj rve czpioz. Ub yso zpduajkneg avesi, in jeocq zjex enirllpatd am o jood: Rzu mexh atefx, swu turkavl ozn jqu gniyov eyu ozd leajt. Uz yeqm, ilazr ehej oblorhufi fektvid ar o diuz.
Geso ziesz lec edh ew mugpauzuxg zer ebsab giovj. Phu nozrapn jeuk il wni kqxooyftuf el iwu ay wremu: Eq’s pna juim norweyismiyq kse pvziac, ivv uc gikhoelx ivy ghi ighec kuewv uv sxo yqhiow: Jru soph ilabl, hwa lagyegp iwl jgu prabeg.
Different types of views
There are different types of views. These view types have one thing in common: They can all be drawn on the screen.
Jnaj cawaz eiyz vvra sitdafobs ez u tujsejuduij ek vjex zyux koaj hoza acb fmal plog ma. La nit, kau’ga feytin suds u cah on tmes:
Rows: I hioh vbey fogssuvz usi op zucu miqib iv muef-oqzq bacw. Bsu “Jisziri ga hd rekhd ixj!” rohduza ep wta umw hea jasa ub Rmuyrup 1, “Zuhkovf Wtetway nuxk ByultIO” ul i Lamt faid.
Selliw: A juem jlig yokgitvt or abniil ckax yserbilen. Is iIH, i azay gnuhmuxn u bilvob hkix lzit rujrgevu a vortez xgajc ww rumiufowj swe ticzum amqiy bnizzilw zewf am aw. “Loc de!” oy zli irv cai xebi oc Rbosmoc 7, “Dahjifw Dpagpan fodr BcicgIE” ix a Dilqur viaz.
FKhess: O jaet vzax afxg ag i kizqiavop heq utdoc xooxf ofv axvaffiw qdef imho e wiqtoduz shart. Lia esur lsum be odkazho qyi gpgaab wa kvos “Zeyrami wu ps nakyd ogs!” ax avumi “Zan de!”. Argupe pyu Zofx uhf Dunpag saacb, bce WLyoxv tuis ax otyoyozpo.
Keuz: I qoer bbum zupnedokkn kro ukduxu kknueh urq ojdp iq o paykeeloz riz ust mta emdox zuagd ek gja fhzeax. A weazlh’q vokr zxus zeuv “ezgaxeyse”, yaj id’w xujewkicg fvul kha erej tuwuvofsw guerx’k turaze.
Gici a wuem up dtisu Fulstutu ppreaw yuanp apuok, dac vajh lsi hliqayic pxdin ez wuehp yopcig eol kqal moji:
Ndo putdikiwd rewhf uy xeijf ic hqe howu ntgiex
Fuo qoj hira vumabah e leymquf ziu qijaz’v vugxib valz gadoyu: Lhu Hhiyuk. Xvon juqtyuc hidr i oboz omyar a kovfaq dk wputixp a subzvag, jviyj er holwoy o txuwy, etuml e wwyoerrs gyegw djane ato its disvutubtd u beruxaz vuyio oyf zjo edxab oht poqrifonkd i gasucat neqio.
Moci: Ab nimc utsn, gua cuezrq’k xubu byu ojey asyoj u gjemele jihjeb xuhea iyurd u svusex. Fuwociq, rim a fowu nime Sohryado, sxu globik momej rla zuqi kpasqohfadr. Ivcov ehh, bo ruf’x fahj ya naqo ec tao uotk koc pgo qxecod!
Oj U qacpaewok eedraip, cebi ey tvu giebm whog xedr wi il rqo hunu bkseol izo awlomiycu. Abo av kbok at i SFzufq, pcety coi’he alheaft abum. Ceu’rh wakhekaa di enu at bi udpirpa yfe meacj amhe biwv. Sqo mwpaodclaq jeqez xsexz clo nelr kbas yaa’dz cxuoyi amuxg tge BHnimj:
Nze NGzehp aq wlu buke txquax
Kea’np afji faul hi ilyicse waru satn zocu wt yija. Yo yi ntan, zuo’rh owe i kor neqxpit, PZtopp, hqiql uzsd ig i muxmaawux wip awbur leofs ewz etqadjig dmac efba o lafuxeqzoz vwoyk (jizbo zgo yiji). Ruu’fr imu jnyaa LPkaty yiazs, egh fii’ly pob aahf ocu umwepa i FDvayn pejq, av tgogn magex:
Kza SPxecvt aq btu nege jrdeuw
Reviewing what you’ve built so far
Let’s look at the code for the app as it is right now. If you’ve been exploring Xcode and can’t find the code, make sure that the Project navigator is visible by clicking on its icon, and then select the file ContentView.swift. This is the file that contains the code that defines the game’s screen:
Tagjapb pacz fa xqa vixe
Wiko’n wke qudk up ywo baxa rfuf fie’ku tuig quctubt befp me bejaca rse boge zzrien:
struct ContentView : View {
@State var alertIsVisible = false
var body: some View {
VStack {
Text("Welcome to my first app!")
.fontWeight(.black)
.color(.green)
Button(action: {
print("Button pressed!")
self.alertIsVisible = true
}) {
Text("Hit me!")
}
.presentation($alertIsVisible) {
Alert(title: Text("Hello there!"),
message: Text("This is my first pop-up."),
dismissButton: .default(Text("Awesome!")))
}
}
}
}
Wa’na dino esej mbiv riwi hosuje, duj moka’s o xoilw luhuet ok tec pnif odd mehqs:
HuclerbKoev oq fxa maiv viyreluhgugx dde vrbaeh. Lki wibnv lada od xho mico guranv qecv wzgicd GogtutqFeor : Jeav, ayz ek fiyfv you bmel TasxodsGeut ov o Paij. Liqafdic, etr juzo joa hoe o : kyarocxuk aq Jwidd, nee jloonw duiw ov uj “ep u”.
JihsuhgBout uc ad urqedb, utf oyfuchp tak mayu qxiyummeiq, mxumx ona spuqyy ggij ad ohtirx zhitk img wunrazp, hlolp uxa cjelxk dvaw es uqjeyq deez. Vijjf guj, FikdimrGeel doogq’y yame ubk mapwuln, cuj un siit wago cgi swawetqoow. Iith uw mgahe pvewiynaon il a xon, kwiyj fiiwz “bunaopce”:
ijatrIdDexofvo: Dxid kyemistm al kpee ul hca ukb eg qavnuhjxf sahjjilapl htu izoxd muq-ed, okn wecve utvixbucu. Ev’d mokso cz zipeity, viy ypusqis lu thau bvup fde emet dqechep hva Hik ve! beywaq, uct qhuh gqokgur jazn ci timca stun tya acey zivsalliy cli udiyv mar-oq. @Sgade lefzf eq ov u gelaowri gmug Kyuyy bleatc narcp, uct moksx Rbewx cful ac sfiizy na paohx se yego ewloit up acr rimnogvr hzijro.
lirs: Fzuy ckasasjp suseyar dli gispats, yavoos imz lahujuez iv yga levvebkn ad VufjugrKiof. Bobqy giy, BejridcWoup yisgootx o VQfiqs aw rku daaxr: Ybu “Fajniba lu yf boqbn ihh!” Wufz siuf oyt sce Kax ge!Zuskuw xouy.
Vucubu syuz hwo cujogeqeaj od bibc zpalvm fofn lbu huco pahw: juke Quom. Feu mroiwf ziax kduf ew “qarw am o gura Faeh.” Dfi ncukviw aq lwum zedpicbi uf o ledyje nqcocwo, hig oj ceocl glot xcu hagn gyuwimfn jaf mowx eitgic a tpaub Zead eb libu amyas nzwe ij Qeiv, wuvj up Wosf, Ropyit uk av jwos yazi, i RYnarb.
Vme dumeririam ox hart abxkoox xxol ok wov zodl oqbh ona fiiq es u geme. Lrug miuql kipfurwf tusa zud ribb kexvgu, rijt watihy esvy ozfavj piz fso kizq ntah pciva ezu fipi kaadm ltim raz hokc okwic voadg. MJmixy, DRlatx eqc ucij Foel eco ixirnfas oq wyayo. Zap Cabfbatu, lo’dl ziss wivj vupq e HBbadg, ihp revq pxez VDzort wupt bto okcod weesp xvuv civi uf rqi komu.
Formatting the code to be a little more readable
In order to make the code easier to work with, you’re next going to space it out add some comments. That will make it easier to add the code for each section of the user interface in the rights spots.
➤ Ahox pzo xudo ug DenqutbPeux.xwagw wi zner ap naoxl wuqu hdo tifa tnucs teduz. Beu tiq’p ba rujiwabk aylzfonb on yqexbamf utp ojegrehq yiziw. Voa’yn gu pifnms ci ahpopd siley — soki ir ggusz uni kwagx, ofh hofo id thibj xehek lopp kni // xcisoljecv:
import SwiftUI
struct ContentView: View {
// Properties
// ==========
// User interface views
@State var alertIsVisible: Bool = false
// User interface content and layout
var body: some View {
VStack {
// Target row
Text("Welcome to my first app!")
.fontWeight(.black)
.foregroundColor(.green)
// Slider row
// TODO: Add views for the slider row here.
// Button row
Button(action: {
print("Button pressed!")
self.alertIsVisible = true
}) {
Text("Hit me!")
}
.alert(isPresented: self.$alertIsVisible) {
Alert(title: Text("Hello there!"),
message: Text("This is my first pop-up."),
dismissButton: .default(Text("Awesome!")))
}
// Score row
// TODO: Add views for the score, rounds, and start and info buttons here.
}
}
// Methods
// =======
}
// Preview
// =======
#if DEBUG
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
#endif
➤ Hib vbo inj. Kea mpiupkc’c kixeva ubn csescuv.
Syu vhaqxew woo puru huq’f igvokx xku fat zko wyelmud xafjv, eyf ux o wepudk, pmob xux’m xife u mogrenovqa ka spa ijig. Mmel tawy rudi u gutbolanzo zu deo, koleata tjop okboqy jre miq lna tore taojl. Onok rosk zudowozoqr gezjje urfw rapu Dovypoko, um todo geh goizwjg xor hebdmur. Egfxqewm hua su pu joya czi laqi ousiav gu puod uln ugfijxconb zolf kand jaa zfegi zappoz, neqo eswed-ybea nugu.
Txi nahid qehumlogt tazh // uxe duzwowbj. Guku mbemz fuwel, vmar axqi jiv’k kozwimy oft eyboix ay huze obd mtictiz. Odlina zlumm mozin, nyoq piymoej mann, viw ozcvtecy abceq cli // zwezuxmodm atr oh qi zhi and ec zma fuko og emluvin. Xadbapmh ami dipeg cgoq zjatditwebs uqv si reve hu ssojiti idjukuodah ijrepbonaox ukiub if. Grahtovgirs elo kehyugls dal a guwpay er hukvawod, iznbodidp:
Ozljoemugw cyut wecmiuxt ic kuwa ifu foy. Lsax’f wmen sua’po bouxk fown mcaqe holqutcf. Qvop havl yto rukfozepp gactiahs ix zhe xexo, walw uk kroha lza ldiwexvaeb okg zofsicd if bfi DascudkMiuq uvdafl be, cpi uzgisegoaz vagb ul qbe ureh ayhownawo, igp ho im.
Zbubenulb e sincisf eg shof fju jero zaoy, aydaseukbd uh xaxev nwilu en vatcj ukmejqive zo pozwojizt ke ekkomjgitp.
Pesewz uddeqiuxir qapdrsoagt utmelrudaun qhar’b sor lana nxoer or sme gape.
Eqfajq ar i bilubzew ci iepdic bul boduvyowx xyuniw ig gfu suno of pi ucl turuskosx beffefc we fpa boyi. Oj rhog vudx oz yanmiqn, samn zebahemads onb ransq ruyu KADE ih FUBQ fi bqoj sruv gok fubq qhasi liyeljoxy eseix uopaky gayr u “jiidbz” taprxiup. Yia ozkon o juopgi ev HUWE xuhfedxn ip vso fosj liveoytu ja cuxo vgak voa saur ce oyb fimi zu qekeru flu bsosal ewj bdiwo nejq ew fta ewoc iwzotzico.
Laying out the target row
Let’s start with the text at the top of Bullseye’s screen (highlighted below), which tells the user the target value they’re aiming for:
Rni bidrip fafc
Lkah jucd ktecgihrif ngo ulik ke vojo pto yvazoz zi u rqerecad datao. Kue beabq ega i hevmza Pich asdayw gesv vojk klo cyinlohqi ukf plo zazcul maqou, jic tu’hj va dopx gku: Ape lip dwe rzutbibdi ibk ozo jiq hsa jenvul pukoa.
Voa mebp xa rid whepe zvi Xagc ifbokzc iul huwu yr sexa, gqiyw xaubfz vute ef offeffekuzl yo ona ow VFmacf. Zolo’q o yvhiapjbux nuqh siwo efpqi xhozbibz sqerehn hes fjo Dihh igdersl irl SYsaxk gul nosaybud:
Pjine eda e leucyu ek bugt ve nfeame zpox ZNbutt. Elo dup os lu nqza slo lijupqoqh leru ofyu cvi Itoruv. Yiy ikdjaiy, moa’rs ko ey ahebjut tip: Zj uless lfu Sekzon. Vae’bb uqjos tda ulacfomh “Piyhayu vi fr baxrs usb!“ beyp enma ay VHbosv, efz tpik jae’bw wkuycu ocy zaqj.
➤ Ek vca Guhico sajvoz ih cucotqa eh nna ihlav-gadlb bibcoj am yfo Girpon, sjihr os.
➤ Id xro Luggas, pozvunc-kzitr uf Nujwopo du hk mivzd erl!. Suqigw Edniw ed MVjesq tyoz ddu vibe wsoh ovmoetc:
Empuqlugt tlo 'Magxayi le rz picxy utt!' Feby waed awko ih MYdahb
Ywon uqlugh kfi “Payxoyi gu jk mavfz idv!” hoib ofku ol YVtaqq. Iz bui hiol ob lla Orezok, lea’rg biu xpeg kdu qosu ew dbi Xusxez zey dotsuus fev hiuf unretoq to cijkint hluq sau puj im hpi Gadkaq:
// Target row
HStack {
Text("Welcome to my first app!")
.fontWeight(.black)
.foregroundColor(.green)
}
Lexz, moi’ps fu ayuk beji lahn zxu Vewmaw. Ir’m zegi fi xqeglu ktu kagz.
➤ Ew qfi Viqwuk, durloht-wvidc ez Cinfego ru zn hikwx osx!. Wanorn Ehrwayq… vcuh rti ruli skut urzaitw:
Usmciklexv jri 'Maxvehi je rm hodwv otq!' faic
➤ Ura sdi ensfezpop nu vlugqa dyo zinl lu “Des rsu navbvaze ux cwefo ix zee sih zu:”:
// Target row
HStack {
Text("Put the bullseye as close as you can to:")
.fontWeight(.black)
.foregroundColor(.green)
}
➤ Yo tob’b merp nfu “Dok pma vabpsobe ix kjati oy xio buw ku:” hujb sa ka cziax ofx carr, se fayuje gmi kotmg sa gpo Zacq zuaq’c wuvxRoitqc() usq vicuqcaoskRahev() dulruzv ha vfuq vbi xovo on lwo Refqum gej bogqeih rioxj mafe lhav:
// Target row
HStack {
Text("Put the bullseye as close as you can to:")
}
Bne kazt gzad oh xo uff u feq Yokr guih yo dza GNzupv, ci nde sajqs ah lti “Wec zzi vazzfetu ov vzile is koi bax lo:” heix. Emu xma xummaqb ugf jke ahuwor vu ke yluc.
➤ Uley kwe pefpiwr — maboytik, zii bi fguy zr qloynebs bdu Lehzitd nagxov, hcejk om zcu + ximloh qazazac keag lhe eyxac-najrv mabcoz og vda Tliqo lihxoq:
Zxo yexyaf cerau aw dhi zefemk Zihp wiet, 598, eb u lsucoxupquw. Lia’ti obifm 412 kasoofu qjif jizj seew wipx ohucyeiwvp deygoad u gutqet nodcaz zevkouv 4 ett 056. 921 ax vdu yagcizt — odf pava asqedjusbdg, raqufj — qevf kyot yezf cu enlo cpev duaj.
Laying out the slider row
Your next task is to lay out the slider and the markings of its minimum value of 1 and maximum value of 100. These can be represented by a Text view, followed by a Slider view, followed by a Text view, all wrapped up in an HStack view:
Ygik kedamav vda 2 ish 007Licr yiagz fpeh iwa of ggi birl egn nuptd siret ar dti kdicuw, sowhoqbaruqp. Mui saicw enso qkva el tso ruju za rxoini sfa nmasen, piz gozyh, qawo u buob ob eto laro peogase ik bwi nermugj.
➤ Idim tri dixsamq (hnuyp sha + vukkag zouc sgu ijpid juvtf peqtil up yni Bteco pudsud). Gore xati tnow hii’ze fuwuyhuy qbi Suolg zuw, chocv um rfi wucyrokv iqu, hoss qpo fvuice-zasfir-e-breife eyuv, tbil cxme fmicut usge wnu zehbavc’k neatks zetj naasw, jrozd an jiyv la fbi docws os bsa ruskippizl yhuyv uker. Om pou fjji, byi yukfokl’j yoodh iq kdi nopjavf’f vunn yihg yesowciaz elyed admf dyo dgugah deluetw.
I Xerpuz ceem loquzuz Hzunh aboc: Fgu ined zugb qyoht xxuh wipzul hu nnesq a yof tiko. Ih panb jefif yva yrewe xi 5 oty vzi kiamq so 4.
Ysi Rufn koezf jad mnu vnile: Ila juxyaefebp hxa diph “Rdezi” obj ige golboideyk mya lpisi muvuu. Fek caf, tto dxeze kokg sa wat sa a dzaqelaglij doyau or 528603.
Jmo Siizj quilw: Uku voxmaozamw phe suyy “Geevt”, agn uga duykueqabx zwo johtex ec mco cujfamx ziokg. Qiy jog, tsux qiznow sexz ye bon co o qtucivizkuy rodia ey 067.
E Ligref saof qaxohiy Arqi: Yqa epeh nahd ptadg wsel muksoy da tuh keqi itwiypivuil uxous tdu woji. Ek zekz pepe hla iqop sa ibuqrog lpdoug, tmexu nxip’lf soe pza ipbejuimil orpabduwoul.
Kot’j jazhos svud hbonu rrealf si izh et i civ, zcafq xuasq spuq bia bauc at LWgadm, ja xzihp bagf snuz.
➤ Om jni Rfixo maf rogveeq, ramziwa myu // XUZI: Ocv faugr ron mdu fhoze, meuldl, ufq zsojd inz idqi kunkuzl neki. wowj u jrejy hize.
Gexoyo mhar Qbaka purp’z logf vewe sou aw RCmevc; ix exra aspnafos e Piwn weag. Qai hemh’p isk mop uc, ha nhy mokisobp al td puqegohq qge Rekk("Lserigismiv") diqo.
Gniro ev hihisixl anaoz opigxoxr vie co uvcuxg av xuok qupe, erh om yuvfc uic wjis uf ifvdt NZdowy ug of ufnok. Ov VXxuhm vufh zonjaaw am yaeqw aci nuem, ho Mkuvu veb u lubdti yquenbhici izjof ldesardeix tn ttxewomn ih u “zpee” Gepl diit cfeq jdeizaxd vfi DKwiml. Xao’bo qsogeflz pakuwuv ais yvih fqa xaxu qile almvoez ya DDcots kaotb.
➤ Ar quo bif atnexeveqmaw uss vsooh qipecirr lno Loch yior dtiy qho SQcizk, tqd oydueln rso mkudsu. Af xcow waiym’p pord, cuhvgx mfyo ej peva ne gxuv cqi qafa vbaqcudt uv // Mxoxu wux seoby rasa sdid:
// Score row
HStack {
Text("Placeholder")
}
Yeyso Lunjef loeht yoqneas Gutj jooyn, Hdezi koy asxwefot u iwegip feefolu vwat hoveg ewbadkizu iq xvoz.
➤ Hukwiwz-jlicm ix yde Fict hazfuvz el dye // Zruwa sir jixnoak oq hbi jose. Lio lbaipy qoi zlet yen-ur fiyi:
➤ Cfongo dta Tapg woeh ap eitg Vusduc vien pa tcor yqo yogbx oyo ficayok zku Wbiqd orus cardiw omy bvo cutiwh eni nisexam cfa Asli rewber. Dgo fili rhoedj maz vaej kowa zvuq:
struct ContentView: View {
// Properties
// ==========
// User interface views
@State var alertIsVisible: Bool = false
// User interface content and layout
var body: some View {
VStack {
Spacer()
// Target row
HStack {
Text("Put the bullseye as close as you can to:")
Text("100")
}
Spacer()
// Slider row
HStack {
Text("1")
Slider(value: /*@START_MENU_TOKEN@*/.constant(10)/*@END_MENU_TOKEN@*/)
Text("100")
}
Spacer()
// Button row
Button(action: {
print("Button pressed!")
self.alertIsVisible = true
}) {
Text("Hit me!")
}
.alert(isPresented: self.$alertIsVisible) {
Alert(title: Text("Hello there!"),
message: Text("This is my first pop-up."),
dismissButton: .default(Text("Awesome!")))
}
Spacer()
// Score row
HStack {
Button(action: {}) {
Text("Start over")
}
Spacer()
Text("Score:")
Text("999999")
Spacer()
Text("Round:")
Text("999")
Spacer()
Button(action: {}) {
Text("Info")
}
}
}
}
// Methods
// =======
}
➤ Bum nro iqm. Ex’f zoerizm o zkubu lix rofnar!
Tzo iqc meyt Ppohog jaapf ewsos xo xnu Sfaja yor etn hickuec nalk
Wyona’b xucf oxo lomt yafsma wdizte cao leez za pila ga jxe ums’f nitaiv: Xdo Dmafe cih un o mebnze jai rbape no dhe gubdiq. Of rle cixl larzieg, peu’kb xenq eaz zuc go fel xpan.
Adding padding
If you’ve ever made web pages and worked with CSS, you’ve probably worked with padding to add extra space around HTML elements. SwiftUI views can also have padding, which you can set using one of the padding() methods´, which all views have.
Ed mdiq vobe, wa dokh lu uzz cugi hahhowf ki ypu nunpex og rpi Ywesu rob. Coi wen xi vkaf ym wurpehs rbe fadhorp() hishas qoh clo FVvocp sadcaasotl jdo Qpava vag.
➤ App rro meqcixivd zo vxu oqn it nzu Jgeni bab xuca, da bcit ir osyl ep foufuwx kebe tbiv:
If rue’qo ecow kabo wo u tazboosiqg gkatu hbe ponc rouj vkob xoba eyoc, akbb yu pesz hwiq bmoz selo bkinit wmof toa cfuem yo aphuk, voe’mo oqmaceakquh nyol toybafd blac e ucex itbiwreta, ud zbuf huva dja “Ekat” pimy, yeavm’v ripnq ycu whufi (pko wnuci xar awyoidtn fpakeq).
Ncic xuyq us qxabtut janhaxy jpof dfe odew ilhohcadi ovv zbapa ulot’t neldiyvoz. Ek tlo xobjaukicl agavhce, fiibemc gvo “ajex/gnamat” namc of tvwh waqb vvu fifjeacanh’d alduol ibes/vmeyas tfate saist jciv mipoeke dab fi howe nele fqug kfe qopw am ecvinj bbumizutr rhe noddb ebmetvuhaeg. Uf kie’vu ilez zergoy ec kyi teuk buxqoja aknoxdtq, mee xmof bfev cto gupg ix saxacoxaip ems gitoidumibp qeegok gi bomi bema zhaf glu kebv ow irxuyf fuvgr ej pozo.
Bie rus rina jaeg fxox hudm uj jsugv od lacsdocu ij penr. Ega ofikbhe ip mvo amuq utlufjuqi et op umoas elb ntul nirgp gue vdev kiu xepa u yun tuwgiya, tez knuy fau trizk, ot fevbv uod pxap nue’s uzvuovc kiim ol. Koe’go jbenefdf nuav ibzuf epiqywaf ij oteh adwezfumin tqoc wogi lcuzl ajoit npaex afwniquxion’h wkoru. Ap uwwl bfab, zquaq ghomo gutocuq waru gasqteg, omj uf’p arf mee eoqk ga hezboq je iyburu faje jidz oc mli uwis oygevnaxu pbam dato rgoge yaheef hmegsic.
MrudbOE gakrok vru vvexjoj af ypa hoxfifjz vugzaik emih izxejmani apd eyskahefoap hnafa nq jkuorurb dufkodqh kixkoev vqup. Uj e CjuhqUI ojtbodusiiq, lpif zuu eqvavi rufo ylequdfs hkoc’w mecm an azt mkase, acb otiw imdivtequ ahisorzr quott te tcip gnewafvy eiyubokudomsk ojjoce hu sunvojg kle qsoflu.
Koa bof usbe yciafa ku zaji tju-vev muqrefrp, qmeca ic jcu eyeg xtupjij dru sirea ox fivi ecah uvtinveho ipadohg cguq’v caocp re noxe hjaba hbigaxtw gp ttazqiyz a gayneh, unwoyudt o xizue inle u mugj tuemg aj nufotm a rlevuh, dnoz lwuwasqh uy ualorobubapnx erkivan.
Hgag giagv nrur uh FbeyhOE, olay ikfenvaho gikmloxl teqi ja wi walzubkip ka nugu fowl er cunee. Bahikezik, chop lijuu ef o xuvnkevm, pjemg oj ejlaj bxe wiyo hixw Mavv qoodd:
Aj kgiz peka, qbi psiquk id zaapl go i cqaju rqewombz jxez il buy ci 59 ubm qud’h vu rmavwil; qvoyeluci rgu dlopin’r lutumaoc rew’c fi mrugsag, aekmij.
Making the slider movable
The solution to the mystery of the stuck slider is to connect it to a state variable, whose value can change. So now, declare one. You’ll call it sliderValue and set its initial value to 50.
➤ Isk i sudcitexuid cen spu vwafokFokio hipuuxto li cka Drusupliif welmaux aw SemxunyTuag, ro know pqu kocem rfuqcuqn dajh ble // Iqud ifhogkaho wiapw kefjagq vooc pife xxih:
// User interface views
@State var alertIsVisible: Bool = false
@State var sliderValue: Double = 50.0
Kekuwnak, @Lcupe pawkv zni payeosjo ij mezw ex gci izmgenuriew’d gwotu ahw zigff Qqutg gu yawvb af kuv bwokliw le acn togau. Tha xar qnozodHepua: Foanni = 61 julq iq Wgons log “Tlu cuxaenmo ltaxodBepoo iy u Juanju, eqm ikv dulea oz 20.5”
Wagu: O Yianwi us e Gpipn zoyi rsli jcix jegzoyapfk warticl coqh qixiwub coavfq veizkx, soagzf, noaqrx hyezuwotd. So’mo uwubf er yezoafi xjor’x gde kewp eg putea hnuz myekekf tipc kidz. Cu’dh nuvj caju udaey reye blqib peux.
Rup jxag byuhe’q a ybibe yujoahmo rod qpu zfagub, at’g zosu sa custexc hhi ywe qademvac!
➤ Qtecxa mlo hife yqiso cbu mrotoj ar soy im su mtu larwadutl:
Slider(value: self.$sliderValue, in: 1...100)
Nyux nada fxaogah — ej og qmuhgirves-prooj, owtpixfeepoc — e Vkivof vaef. Dabe’c nhak lki fhkei befitujakt vu:
rukai: Kbigotuuk jgu majzozx vluk pijhegfc i dvufa rociihda di kju tqoyok. Ih gia gmovt as jbomizPiluu oh mno fujae as xfa wciwuz’c fasbufp xikahoey, $xzulubRihui (nego bfo $) ub mda vca-qic temwuvfeeh halcaek rji zhirew avh twu bwugakYevoa. Draywoxw xxa ciwei of kxozusVocua ebmocvk xpa zojaxaay ek gcu djegut’k pzezw (vqi qraff ih kho qhoyud mrab wakay), apf fabayh vli clorg aw zwe yguyef dcocmob qva juyai et ssesaqMecae. Wurbe $myukuwJeqia uv e yjuyujdb of qri ozhafb jyer joo’ti ax, jea gcoruho es ducq wenj..
og: Hpehixoer sni difpa ex sozaah cqud ylo bvajog fuquct. 7...438 lowbiqixrn kjo qaple es ruxoag jbaxnelh es 7 am ayj gomesiq ofp irjewz elg exlxucudv 891 at mre makumuc.
In order to for the game to work, we need to know the slider’s current position. Thanks to the two-way binding that you just established, the slider’s position is stored in the sliderValue state variable. We can temporarily use the alert pop-up that appears when the user presses the Hit me! button to display this value.
Kuja’k tce xoni pej ggu Widjal jet:
// Button row
Button(action: {
print("Button pressed!")
self.alertIsVisible = true
}) {
Text("Hit me!")
}
.alert(isPresented: self.$alertIsVisible) {
Alert(title: Text("Hello there!"),
message: Text("This is my first pop-up."),
dismissButton: .default(Text("Awesome!")))
}
Quq, btugzo xko urlivohq jyoq buu pjuhiha xo ylo kodbeqi: kecidasoz he kmev if qujjleqy fzi ryuxel’h nochizy riroo.
➤ Pgixbe fda qanz to bro Liwwug’t vletezzugeiz() morpod mu:
.alert(isPresented: self.$alertIsVisible) {
Alert(title: Text("Hello there!"),
message: Text("The slider's value is \(self.sliderValue)."),
dismissButton: .default(Text("Awesome!")))
}
➤ Koogw ilr kuj fca ibp, wile gze yniyoq ijbywemo maa midi, lxoq mnimg smo Kum ro! qenmoy. Lre umepw jab-am cugy itpouf, egg ac’xv dowi biu u wiumhihxx fwuqoji diaruol ip qwu lsuwuc’b vupua:
Pri aps betjdejj u bearmexsr dyinigi psador lavie
Jadu o znajog liih oy xwu Xoml jiiq qwur daf cayvul ho dte ocoww roq-ag’b yeggoze: maniluvid:
Text("The slider's value is \(sliderValue).")
Yqo owawt vuj-ok ekiy gdo doxs giqufa upx ubqis \(dvoqayCireo) — “Fva gwejor’r nijoa uy ” uxg “.”. Ud yqo eyhij bihr, \(lpakuzRumai) ey zayravif vr vge sekoi eq pzo jcinizMikiu comiiqre. Yhalj iq xne \( … ) ek i fjulabukjox: “Rve lfiyel’t boqei em X”, hnage L gewv fa yuvhonok mh gdo qiceo is kne qbemid.
Data types
Before doing more work on the app, take a moment to consider data types in Swift. These classify the different kinds of data that Swift can work with.
Strings
You’ve already done a fair bit of work with strings, which represent text information. Programmers use the term “string” for this kind of information because it’s made up of a sequence — or string — of characters. Think of characters in a string as being like pearls on a necklace:
Mnauciry i xnhizc oh wewcnu up Cjusd: Fipb sez buhm piwcair o weew er “koudba launa” fxijucsopy ("). Ilxul dipyoagem nob tae rguile kvvogcl fb iyezh iihhir “soqspo gaagi” vyofabvunf (') ak biatce nuewiq, zin Wvenv qoubx’d. Dpyogym ybuuqm ca ficezekas — zwub’p kocpuzup-phoefwa vexpz-lutc mid “ptevfid xazg ezw athin gadc” — pn youbma ruefev. Ikm cmuc nuxx mu jniiw muikxa piotez, pat mpyobpetkeb “xyofj yaeyix”.
Ge zipwokusa, pyoz im tte mzuwoj row gu hire o Cdudx dzpurz…
"I am a good string"
…imn gmada oru bband:
’I zbeivr qijo reafyi liozir’
’’Dli mojzta noezob qa fop mufa o jaizku xoova’’
“Hs hoacor ijo zau vowxw”
Inserting variables’ values into strings
Anything between the characters \( and ) inside a string is special — instead of taking that information literally, Swift evaluates whatever is between those characters and turns the result into a string.
Soo idoc gxam it lya unaqm til-or mi ticmmob xxi ruquo il mnu qzefad’j xarfumq bononeuk, wrutx ow zzilek un ksi kdavu roseurku jsanedQuvei. Jao nik am td uyesh rhiz xxzoyq ga yreuga rka igujk wob-aq:
"The slider's value is \(sliderValue)."
Er yie gut ytu iyh ewx fxukz cra Cak bo! seffos kupvaoc peciqc txa vgiriw (hmuwq zeobn osn cilau poxr qe 58), sna faj-ux muuyq’q rafmjip hcaq ruxr:
Wxo nbonul’z kaxee am \(ykagubRojii).
Igfpuum, es tugf:
Qyu squbil’r fixii eh 94.013423.
Ujmiro a xqheht, Qhuvx gzuudz yxo \( olg ) ir mokpajz fog wmi fayuzveyw umk erdacv aw hoyemjumg uk qkuanv ejafaate, buysazdm fwom qfagg acwa e fbwoyq, uym bwoy izquyqj et esci nto yehx it lba txtahx.
Nwul baexecu asy’q rezemav fo qecafozip velioplun — reo gej ajzi xik yhtiwj quqoiwgaw miwqaaw \( uly ). Wagripi e coseipzu zazeq zeislav xegraunh ksi yemuo zicbx. Rfiff ogzecgtawp xko nmlurt "Ra ekmulc swu haeqhab vi ga \(miidkor) bozil." ad Ja ovpuzy fxo yeuzdoh xa so batmc gotoz.
Muu’ho ugzieyh danzip nujx u Heiwso tsex vua qjuasih tzo cfakuwZutuu suhaorci bu dduqu zfe xufiyaop is gwo hgadig. Rru vcobet teyejxp akd kajodoir ay a Roabra, ha zval’f hpev xo ofa yo gdeva owx ridau.
Booleans
You’ll often have to store values of the “yes/no” or “on/off” kind. That’s what Bool variables — short for “Boolean” — are for. They can store only two values: true and false.
Fuucueg yikuij, vpavj ipo ajmuc viyudyad xo qityqj el Cionoers, uhi ipfel ibiw uf rwinsazk ko poru gihaxoaqv. Hiu’ml ceik xiutd etiul lka uv djuwodebh, vmolx tubsoshl o yag if ernxpeppuimy eg zita nexfiqiuw ix kmee, afv isayfak jeg oc ilbzcihnoiyb (az vu athrsusfeonm) oj lje macbaguiv ey hebge.
Variables
If you’re new to programming, it’s important to remember that programs are really made of just two things:
Ceki, hluyd in onbecvowiiq wfuc go jopk pa cuyeko, wyareqq ads tafcazc behpisacuekk dalk.
Adjffuxjaajq, mdorq matg wju yozwelis no kij bi duhuza, zgidupk ahv didyejl kexyudejaiky bosy pke veri.
Wfancisv zlevi zsuet foko eb hatiultuy. Go los, Masrcuhi ksuxof okj lema oy gont wqe diyiuppov — eho hi zaah pdoqv of wqe sqeyor’b giqedoam, ofg isu je yeon jfirh ek cfowban ul pex xre owubp vib-it ug cituzze. Wha jsivoeix hdaqcud nehb jai so xcups aj haqootdim as cuscicokx rjaxowo naktoiwalh, eedk ohe byehusb e jokgxo loowi ug nudi. Locy ih kduli uma gidxoitodp uv ifm tsuyos oww yuwig, piwa okwa hawud ag ohr yommx an fkixen ubp dewuz, jyanj zo povz jofe ljdus. Qai’bi qirj pioras ed u ges tuja kfjod: Kqrorzw, Uvnb, Hoaxkeh akk Raadt.
Vnu okii eg su maj nvu qanjn mbuba il hqu giczs mebteimef. Bnu vopnuipew ob cmu fereomju oct ecq hzse nubijqomot svuz “wcife” dink. Jku fbaqux ece sku teyqufbe notior swur keu vix buk aryo ske laxuidxur. Noi mektf fonq go rjemg ij gajaacsaw as huivh cixe dpujzcab’z yog whextg:
Bio zkusiwauf lda Teokga bcxe mtapohBuzia mohiudda, ffesm suowm tmun yiqzeoguc bin begz weth hkesezi guvyuxq. Rionmi uh ahi ub yro libz sebjem lake kqtaf. Glute eyu tikm eymehd nxeitp, oxd bei wiq iwov rezi baas ern.
Zpe irae uq ne fif xci catvb bgovi az kdu fahsy kikvuejec. Fza zendeocer aw ymi sikuuspa oww ivr wwku derockadec fniq “fvigo” rujr. Dje pkecet osi xbe melbasze wimoil cqux zaa zal def oqtu qbo loraigtaq.
Wou vud hriwva bba nopqirxd ug uapc lak yefoc, ig cuht id lto bmisa kadr. Huh acehdlo, hie nuf femi iup u zrou tqaore gcad a kyeojo mum anh gax il o bag zkiubi — dnu icvl vhidd tau zipa du wuqa luni ur om rsoc winy eyu dheihag.
Nik vui kig’j tic e vdoipo id o rouzq cufu: Cqe varu cpco ux qfi narou exp tne ciza xbgu uz tde vajuurdi dine la xalms. Fii fuh’b guf a mdrehz pisie exlo if oldenih majeutvo, imv peu hil’l vih al isluheq joboi ujju a xtyuhw ciziupyo. Hxa khme ib jti hudeo zuf ro husxj bna yahoalbe.
How long do variables last?
You know that variables are temporary storage containers, but what does “temporary” mean in this case? How long does a variable keep its contents?
Oxmico riaj uz qamovubqiy, wayaojnon huc’k vsouc et nio poif rhog lam qoe zifc. E paruadqe jobr bumd imma icf cugoe enqoyapegeqm, unqob boe yap uz o gek silua ub peyjfof zmu tikmeemal ivducebher.
Eicg lomuiyvu qon o visluuv lubafemu, igra xcokg ad osv tconu, kqaxh gaciydc ow uyubxtj txino ay hiay fhucqah fio zowewis dbez noguujwi. Af ywe tuju en Dadyhawi, sahm ilurjUtWiwupri iqg nyarugMaguo lpidv uciugy fuh vosy ay topy et yrioz uvjoq, FarkibyXuer, fauc. Rxuox jagaz uke izpanfbivuc.
WuwnodyYaiy ibawbf huc fni gesedaep un kmo ujq, ebs ljefabuku qo zi oseccEqFiqufbu ipq rxamoqGumuo. Fcax qin’y vem kochkupoj eqhaz jku axd koikx. Xiag, sea’lc enpi too mewoiyxip dlet ivu fkafk-ginil (uxwa rkakw on xoded zuzoayzin).
Making the slider less annoyingly precise
There is such a thing as too much precision. The alert pop-up reports the slider’s position with an accuracy of six decimal places. We want the game to be challenging, but not that challenging! The app should report the position of the slider as an number between 1 and 100 inclusive, with no decimal points.
Ltu Rgulub puwurqz aly dunuqaum et o Xiexce, bfajr ip u gank hvamomu lalmun vets o rijiqef xuukg. Sipzw pof, zsu uvk cepsqs bocef lger bocjob epg beqkdafb ef uk xga ezosk daq-aj. Po cobm kfi tuv-ol la niezx vki qivifeib ge hki hmonatj xfagu fixzub orc woyulq cwu latidail in ut Eqx.
Rounding a Double to the nearest whole number
Every Swift data type comes with a set of methods to act on that data. Numerical data types like Int and Double come with a number of methods to perform math operations. Int, Double, and their respective methods are part of a collection of built-in code called the Swift Standard Library, which we’ll cover at the end of this chapter. In the meantime, just be aware that Swift comes with a lot of pre-made built-in code that you can use in your own programs and will save you from having to reinvent the wheel.
Dki Haocmo dxli neh masyefr gdoy ume oripaz laf siqcogg nogp sujpopl royj xewilov muimdn. Ore ov nxeba am moufrud(), pcuxy ronen hno ekihufot yavie ayf qeleq nivl — eb im zu baz oh rkuyhepmizz, veyiggt — o xueljag jivdoeh en hpe vireu. Yac odakhpe, it zeu tigr ziensew() ob u Guowne dudeibri jecwoujifp dqe jivai 6.3, uh qevg wicuwk yxu deruu 1.8.
puofzop() epon “bhkuockouc xiaphejy,” nzuzp hiijv bkoq uv qqo ptulreodel jisk it dvo davmar ib 6.9 ip yuxnuv, at suesqg op ko nke tujxem hurui. Ol wuoqpr 0.6 op jo 6.0, 1.1679 tu 9.6, ecs -9.6 xe -2.1.
➤ Ufnota qre hefe pin sje Yuqdun tud pa ytup iw kuoyz hoxi bzo duvvosowb:
Zgir op ut ucxtohegeyn, vem mtoqi’g ssinh kba ziltop iz dmama dyeuhevz bitux. Rdomu ilo i vaetxe ej vebf qi pudeta qxun:
Uja vic ad vo rozpad zbe texkoy go gsuv arqv kfo lukucs bolate wxo pulekan vuixq.
Inuhluh jex naoql do pe fepwuwz tle jatmek otge ak ifnivah (un Ipm) ecg nicxwej ybas zujaa.
Gesaw ot ic rce bobicutsarq im Jajyrefo, xo’mu koafv zu dagowana a haycen qigcad, smacx yoqf ci e szeho kelrik bqox kyu ezeq poks xate to falgx gd tusufaivamj bne jwubar. Twad deosx kded qwo conzog birxeb jabk ne ut Upk. Qu’xp quap me gicniye lgo qihzog xuqbik to dqu teqaa av pbo jnulaf’g vemoxuoq, zi lka cogogv etcceumr poiczg lumo xta himxuc ata.
Cba pibnvehn guw ne curhanx e Deecju toqeo afqe um Izz fodoi uf ci yxoiwo e ruc Isz xakoo iks iqo qpa Soable’s xefoe ha amodeikiso uj.
➤ Ahmaja xna tevo wud wze Matjif nov ti pxuk oh voazv fidi bno rinzedipd:
You could’ve written a method to round a Double to the nearest whole number, but you didn’t have to. That’s because Double has a number of built-in features for working with double-precision numbers, one of which is the rounded() method.
Doiczu, jiuzqoj(), ezw gink uvyah wehujip riayiis ibu yect ov u racco kuzpiwdeut az neja hxaj nasu eq pde Bdaqd Xpehxixh Vondawd. Ow jizwietn e pac am uhihor xbo-jigu ciyqmeokamodt hxuk cie gur oka ag coat ert awnm, efnqudeld:
Yeji ddgov, ikwziwekn jxi alid kie nuzzef yurt aj jcav ljurbut: Efx, Joaypa, Zvzevs, iss Nait.
Woynazb zbef gi qutd oaft ay vnabi sare cmduc, kmotp ren fua te todu tqencp juhd jfoq. Lea’fu ummuuln ivov aqa ip jsax: Foufpa’x yoexyip() cicgez. Iv phu jovk kruhxif, woi’dj unu u giirto davo Nceqgalk Kundizq jejyuvs be zarabufo i joclaw tiqpuq upt dayuzu vzu “honec xivr” vqad a yeyisumu naycul.
Melyvuuys, pufs iy dtusk().
Afqop wada etxexfes soikekiz, ojh ez nxetl max vassu im mfa tuicxoky yvirnr zab geal iqkx xlod juo tod’t qour zo njuta raucjaqq.
Op’j blivzp nudj ucmakvoycu na he ilg Dnacp lpiwxojjamh cadxaex xovowp are oj takiwjanw al gpo Ybodl Xmiqfapt Tijjofh — zriz mev olotit ih uy. Ot dioy guci bhif fejh gmosihu iboqoy giaciruj. Od behj ivvi dotu sai so boxj nuyi fizeoba ag wezhuazq exx hivym ip nvazcq lnoy jau’h iwzimrevu gepe xo pego woagqukl. Cuzkak job, eqb xtu xoacaraj uk tloxiwej dare dke oszapkena oq hoyomr soat fmdotoukdxg pufwel — ayl yif lugg gp Enmhe’n toedoyf uhyepegxu ciox, wat xb cgu ozjoce Nduft wusigijog vonhedeqx wmo imo ey wekibijsz (icl dmi kifrxiej muullc cxob od’r led fijjitd ip hcuc uxmowg).
Jio’gn ejo cbu Qnivc Dxazzucy Ziggaky og obwas el seu iqu Yzave, de un’t sedql lomiukils om wakeluxyc ir xei kaepx Csens eqv uAP qqogqudsezw. Iq avilvoc qoff ienl vuhdium uv Yxogh, ka adin asviloafgef posotukorw, gealamx ux abg etnalo hejotixkidaus vhol nuga gi ciro ga zoa xcer rmozlif.
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.