4. diel - Jednoduchá kalkulačka pre iOS vo Swift
Minulá lekcie, Swift UI pre rôzne displeja a Autolayout bola stále oddechovější a skúšali sme si
pozicovanie komponentov pomocou Autolayoutu
. V dnešnom iOS
tutoriálu sa konečne vrhneme na programovanie! Prezradím, že pôjde o
jednoduchú kalkulačku.
Ešte, než začneme so samotnou kalkulačkou, si ukážeme, ako prepojiť naše UI (teda jednotlivé komponenty) sa Swift kódom, aby sme s nimi mohli pracovať a reagovať napríklad na stlačenie tlačidla.
Prepojenie UI a kódu
Aby sme mohli komponenty akokoľvek meniť za behu aplikácie či sa pýtať na ich stav alebo dáta, musíme ich mať prepojené s logikou. Práve teraz sa nám bude hodiť Assistant Editor, ktorý sme si v úvodnej lekcii predstavili.
Najskôr sa uistite, že máte otvorený súbor Main.storyboard
.
Prepnutie editorov nájdete v pravom hornom rohu - ikonka dvoch kruhov cez seba.
Po prepnutí by ste mali vidieť dve okná editora. V tom prvom a ľavom zostal
hlavné storyboard a v druhom máte otvorený súbor
ViewController.swift
. Práve ten je prepojený s našim
controllerom. Všetko je už v projekte prednastavené, ako pridávať
controllery a tým ďalšie obrazovky si ukážeme v nasledujúcich lekciách.
Ak náhodou v pravej časti nemáte korektné swift súbor, môžete si ho
manuálne vybrať v navigácii priamo nad editorom. Namiesto Automatic zvolíte
Manual a preklikáte sa k súboru.
Teraz konečne môžeme začať s prepojením UI a kódu. Označte
Label
, ktorý sme na začiatku tutoriálu pridali, a za držanie
Ctrl kliknite ľavým tlačidlom a kurzor presuňte do editora sa
swift súborom. Zobrazí sa vám modrá linka a nápis "Insert Outlet or Outlet
Collection". Pustite tlačidlo myši a zobrazí sa dialóg nižšie.
Namiesto Ctrl a ľavého tlačidla môžete kliknúť a ťahať pravým bez držania Ctrl.
V dialógu stačí zadať meno vašej komponenty, takže napr.
myLabel
a kliknúť na Connect.
Gratulujem! Práve ste úspešne prepojili komponentu s kódom a váš
Label
je možné upravovať. V Controlleru je pripravená metóda
viewDidLoad()
, ktorá sa zavolá vždy po inicializácii UI
Controlleru. Tu môžete vyskúšať, že s vaším Label
em možno
manipulovať. Napríklad mu zmeniť text a farbu.
override func viewDidLoad() { super.viewDidLoad() myLabel.text = "Hello from Code!" myLabel.textColor = UIColor.red }
Akonáhle prepojíme komponentu a v kóde sa nám vytvorí
@IBOutlet
, musíme si dať pozor, ak budeme túto referenciu
niekedy mazať (daný riadok kódu). Napr. keď zistíme, že Label
nepotrebujeme meniť a zmažeme tento riadok kódu, musíme tiež odstrániť
prepojenia, ktoré sme vytvorili. V opačnom prípade nám aplikácia pri
načítaní Controlleru spadne az chybové hlášky nebude veľmi zrejmé, v
čom je problém.
Pre zmazanie prepojenie stačí pravým kliknúť na Label
buď
priamo v UI alebo v zozname v pravom stĺpci a pod REFERENCING outlets a
odobrať prepojenia.
Reakcie na stlačenie tlačidla a ďalšie udalosti
@IBOutlet
nie je jedinou možnosťou, ako prepojiť UI a kód.
Druhou je @IBAction
, ktorá reaguje na akcie používateľa.
Najlepší príklad bude tlačidlo, ktorého prepojenie si ukážeme. Pridajme
Button
do nášho Controlleru a ak nemáte otvorený Assistant
Editor, tak ho otvoríte. Skrátka všetko rovnaké ako v prípade
Label
u vyššie.
Akonáhle ste tlačidlo "presunuli" do kódu a otvoril sa vám Outlet
dialóg, tak v prvom rade musíte vybrať Action z ponuky Connection. Potom už
stačí len napísať názov (metódy, ktorá sa vytvorí) a osobne Type vždy
mením z Any
na typ kontrolky, ktorá prepája, v tomto prípade
teda UIButton
. Kliknite na Connect a to je celé. Vaša nová
metóda sa vykoná zakaždým, keď dôjde k stlačeniu tlačidla. Osobe názov
metód pre tlačidlá zakončuje v štýle Btn_Click
, takže v
ukážkovom prípade by mohlo byť testBtn_Click
.
Tvorba jednoduché kalkulačky
Aby sme si tiež nové veci vyskúšali, vytvoríme veľmi primitívne
kalkulačku. Založte si nový Single View App
projekt. Ja zvolil
názov projektu SimpleCalculator_ITNetwork
.
Návrh UI
Teraz je potrebné začať rozmýšľať, čo vlastne budeme v našej
kalkulačke potrebovať. Chceme vykonávať operáciu medzi dvoma číslami, čo
znamená dvojicu Text Field
komponentov a tiež potrebujeme
tlačidlo (Button
) pre výpočet.
Tiež by bolo dobré mať nejakú chytrou voľbu pre jednotlivé matematické
operácie - sčítanie, odčítanie, násobenie a delenie. Pre to sa bude hodiť
komponent PickerView
. Rozmiestnime komponenty na pripravený
View Controller
, určite do hornej častí, pretože v tej spodnej
bude pri zadávaní čísiel zobrazená klávesnice. Výsledok bude vyzerať
zhruba takto:
Pozadie Controlleru som nastavil na modrú, aby boli osobitne
TextField
komponenty vidieť. Aby sme nemuseli nastavovať
constraints pre všetky komponenty, tak využijeme StackView
.
StackView
Vďaka komponente StackView
môžete ľahko skladať buď za
seba alebo pod seba, bez toho aby ste im museli nastavovať constraints.
Zarovnanie (či už na stred alebo cez constraints) potom nastavíte iba tejto
komponente.
Okrem vlastnosti Axis, ktorá určuje či sa komponenty skladajú
vertikálne alebo horizontálne, často využijete Alignment,
Distribution a Spacing. Prvá zarovnáva, druhá určuje, ako
sa správajú inak veľké komponenty a posledný určuje medzery medzi
komponentmi. Ideálne si teraz do StackView
vložte niekoľko
ovládacích prvkov a tieto vlastnosti si preklikajte.
Najjednoduchšie komponenty do StackView
"upracete" ich
označením a kliknutím na Embed in v constraints menu, ktoré sme už
používali. Potom je nutné vybrať Stack View z ponuky. Po vložení
sa vám môžu komponenty mierne rozhádzať, stačí si ale pohrať s
nastavením StackView
. StackView
je tiež možné
pretiahnuť z knižnice komponentov (tu ako Vertical Stack View
a
Horizontal Stack View
, orientáciu ale môžete zmeniť) a rovno si
vybrať orientáciu. Takže ideme komponenty do StackView
upratať.
Označíme všetky pridané komponenty (pomocou ťahanie myši alebo
napríklad pomocou Cmd + ľavé tlačidlo myši v zozname naľavo) a
v menu, kde sa nastavujú constraints, klikneme na tlačidlo Embed in a
vyberieme Stack View. Týmto vlastne vložíme nový
Stack View
a rovno nám do neho Xcode vloží označené
komponenty, takže nám ušetrí prácu. Výsledok je rovnaký, ako keby sme
Stack View
presunuli z knižnice a komponenty do neho manuálne
umiestnili.
Po kliku na Embed in stačí vybrať:
výsledok:
Pravdepodobne sa vám teraz komponenty trochu rozhádže. O nič nejde,
nášmu novému StackView
nastavíme constraints 0
od
ľavého, horného a pravého okraja.
Ďalej nastavíme constrains našim TextField
komponentom,
môžete ich pomocou držanie Cmd označiť obe. Ľavú a pravú
CONSTRAINT nastavíme napr. Na 10
. Tlačidlu nastavíme nejaký
text, napr. "Calculate". Ja zmenil ešte farbu textu na bielu kvôli modrému
pozadia. Nášmu Stack View
môžeme nastaviť vlastnosť
Spacing
, aby komponenty v ňom neboli tak nalepené na seba.
Užívateľské rozhranie by malo vyzerať zhruba takto:
Zostáva posledná drobnosť. Našim TextField
nastavíme v
Attributes inšpektorovi vlastnosť Keyboard Type
na
Number Pad
, vlastnosť nájdeme v kategórii Text Input Traits.
Týmto sa pri zadávaní rovno zobrazí klávesnica s číslami.
V Xcode si môžete prepnúť náhľad pre jednotlivé zariadenia a uvidíte, že sa naše UI samo prispôsobuje.
Kód
Týmto naša práca na užívateľskom rozhraní končí a presunieme sa do
kódu. Otvorte si v Xcode Assistant editor a vytvoríme outlety pre naše
TextField
komponenty a tiež pre PickerView
, ďalej
action pre stiskutí tlačidla.
@IBOutlet weak var firstNumberInput: UITextField! @IBOutlet weak var secondNumberInput: UITextField! @IBOutlet weak var mathOperationPicker: UIPickerView! @IBAction func calculateBtnClick(_ sender: Any) { }
Pre PickerView
nám nebude stačiť action, musíme namiesto
toho nastaviť náš controller ako zdroj údajov a delegát. K tomu slúži
dvojica protokolov, ktoré pridáme.
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
Potom stačí tieto vlastnosti nastaviť v metóde viewDidLoad()
pomocou self
.
override func viewDidLoad() { super.viewDidLoad() mathOperationPicker.dataSource = self mathOperationPicker.delegate = self }
Týmto vlastne PickerView
hovoríme, že sa náš controller
postará o dáta a celkovo bude komponent obsluhovať.
Nepôjde nám build, musíme totiž implementovať dvojicu metód. Xcode nám ich pomôže vygenerovať:
func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return 4 }
Pretože vieme, koľko komponentov a riadkov budeme mať, môžeme pokojne
"natvrdo" doplniť počty. Zostáva posledná metóda, ktorá nie je povinná
pre funkčný build. Nastavíme, čo sa vlastne v PickerView
má
zobrazovať.
let mathOperations = ["+", "-", "*", "/"] func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return mathOperations[row] }
Aplikáciu si môžeme spustiť, aby sme sa presvedčili, že všetko funguje podľa očakávania. Dizajn nie je najlepší (vlastne je hrozný), ale o ten nám samozrejme dnes nejde.
Teraz si implementujeme akciu tlačidlá Calculate pre výpočet.
@IBAction func calculateBtnClick(_ sender: Any) { let firstNumber = Int(firstNumberInput.text!)! let secondNumber = Int(secondNumberInput.text!)! let selectedMathOperation = mathOperationPicker.selectedRow(inComponent: 0) var result : Int switch selectedMathOperation { case 0: result = firstNumber + secondNumber case 1: result = firstNumber - secondNumber case 2: result = firstNumber * secondNumber case 3: result = firstNumber / secondNumber default: result = 0 } displayMessage(message: String(result)) }
A ešte metóda displayMessage()
, ktorá nám zobrazí výsledok
v dialógu s tlačidlom pre zatvorenie. Tento spôsob som zvolil aj z dôvodu,
aby sme si ukázali jednoduchú tvorbu dialógu.
func displayMessage(message: String) { let alertController = UIAlertController(title: “Result”, message: message, preferredStyle: .alert) alertController.addAction(UIAlertAction(title: “Close”, style: .default, handler: nil)) self.present(alertController, animated: true, completion: nil) }
A môžeme si skúsiť niečo vypočítať:
Výzva
Ako som už spomínal na začiatku, Autolayout
je komplexný a
pravdepodobne vás bude zo začiatku často otravovať. Zároveň vás ale bude
sprevádzať po celý čas vývoja pre iOS, takže je potrebné ho
zmáknuť.
Ešte než sa vrhnete na ďalšiu lekciu, skúste si všetko poriadne
precvičiť. Vyberte niekoľko svojich obľúbených aplikácií a skúsite
"skopírovať" ich UI vo svojom projekte. Stačí umiestniť komponenty na
rovnaké miesta a nastaviť constraints. Dole si potom v Xcode zmeňte
náhľadové zariadenie a presvedčte sa, že všetko funguje ako má -
komponenty sú na sprvnu mieste a nevznikajú medzery či ďalšie problémy.
Komponenty pokojne môžete reprezentovať View s rôznymi farbami, ide nám
vyložene o pozície a správne nastavenie Autolayout
.
Ukážte, že to s vývojom pre iOS myslíte vážne a pochváľte sa screenshoty výtvorov nižšie v komentároch.
Keďže sú princípy zarovnávanie komponentov na kontroléra pre tvorbu iOS
aplikácií veľmi kľúčové, v budúcej lekcii, Zoznámenie sa s dôležitým komponentom TableView , si precvičíme
Autolayout a StackView
.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 80x (60 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Swift