Geek tričko zdarma C# týden
Pouze tento týden sleva až 80 % na kurzy C# .NET.
Tričko zdarma! Stačí před dobitím bodů použít kód TRIKO15. Více informací zde

Lekce 4 - Jednoduchá kalkulačka pro iOS ve Swift

Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem.
Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Minulá lekce, Swift UI pro různé displeje a Autolayout byla stále oddechovější a zkoušeli jsme si pozicování komponent pomocí Autolayoutu. V dnešním iOS tutoriálu se konečně vrhneme na programování! Prozradím, že půjde o jednoduchou kalkulačku.

Ještě, než začneme se samotnou kalkulačkou, si ukážeme, jak propojit naše UI (tedy jednotlivé komponenty) se Swift kódem, abychom s nimi mohli pracovat a reagovat třeba na stisk tlačítka.

Propojení UI a kódu

Abychom mohli komponenty jakkoliv měnit za běhu aplikace či se dotazovat na jejich stav nebo data, musíme je mít propojené s logikou. Právě teď se nám bude hodit Assistant Editor, který jsme si v úvodní lekci představili.

Nejdříve se ujistěte, že máte otevřený soubor Main.storyboard. Přepnutí editorů najdete v pravém horním rohu - ikonka dvou kruhů přes sebe. Po přepnutí byste měli vidět dvě okna editoru. V tom prvním a levém zůstal hlavní storyboard a ve druhém máte otevřený soubor ViewController.swift. Právě ten je propojený s naším controllerem. Vše je již v projektu přednastavené, jak přidávat controllery a tím další obrazovky si ukážeme v následujících lekcích. Pokud náhodou v pravé části nemáte korektní swift soubor, můžete si ho manuálně vybrat v navigaci přímo nad editorem. Místo Automatic zvolíte Manual a proklikáte se k souboru.

Nyní konečně můžeme začít s propojením UI a kódu. Označte Label, který jsme na začátku tutoriálu přidali, a za držení Ctrl klikněte levým tlačítkem a kurzor přesuňte do editoru se swift souborem. Zobrazí se vám modrá linka a nápis "Insert Outlet or Outlet Collection". Pusťte tlačítko myši a zobrazí se dialog níže.

Místo Ctrl a levého tlačítka můžete kliknout a táhnout pravým bez držení Ctrl.

V dialogu stačí zadat jméno vaší komponenty, takže např. myLabel a kliknout na Connect.

Propojení Labelu s kódem v Xcode

Gratuluji! Právě jste úspěšně propojili komponentu s kódem a váš Label je možné upravovat. V controlleru je připravena metoda viewDidLoad(), která se zavolá vždy po inicializaci UI controlleru. Zde můžete vyzkoušet, že s vaším Labelem lze manipulovat. Například mu změnit text a barvu.

override func viewDidLoad() {
        super.viewDidLoad()

        myLabel.text = "Hello from Code!"
        myLabel.textColor = UIColor.red
}

Jakmile propojíme komponentu a v kódu se nám vytvoří @IBOutlet, musíme si dát pozor, pokud budeme tuto referenci někdy mazat (daný řádek kódu). Např. když zjistíme, že Label nepotřebujeme měnit a smažeme tento řádek kódu, musíme také odstranit propojení, které jsme vytvořili. V opačném případě nám aplikace při načítání controlleru spadne a z chybové hlášky nebude moc zřejmé, v čem je problém.

Pro smazání propojení stačí pravým kliknout na Label buď přímo v UI nebo v seznamu v pravém sloupci a pod Referencing outlets a odebrat propojení.

Odstranění outletu v Xcode

Reakce na stisk tlačítka a další události

@IBOutlet není jedinou možností, jak propojit UI a kód. Druhou je @IBAction, která reaguje na akce uživatele. Nejlepší příklad bude tlačítko, jehož propojení si ukážeme. Přidejme Button do našeho controlleru a pokud nemáte otevřený Assistant Editor, tak ho otevřete. Zkrátka vše stejné jako v případě Labelu výše.

Jakmile jste tlačítko "přetáhli" do kódu a otevřel se vám Outlet dialog, tak v první řadě musíte vybrat Action z nabídky Connection. Poté již stačí jen napsat název (metody, která se vytvoří) a osobně Type vždy měním z Any na typ kontrolky, kterou propojuji, v tomto případě tedy UIButton. Klikněte na Connect a to je celé. Vaše nová metoda se provede pokaždé, když dojde ke stisku tlačítka. Osobě název metod pro tlačítka zakončuji ve stylu Btn_Click, takže v ukázkovém případě by mohlo být testBtn_Click.

Navázání obslužné metody na tlačítko v Xcode

Tvorba jednoduché kalkulačky

Abychom si také nové věci vyzkoušeli, vytvoříme velmi primitivní kalkulačku. Založte si nový Single View App projekt. Já zvolil název projektu SimpleCalculator_ITNetwork.

Návrh UI

Nyní je třeba začít rozmýšlet, co vlastně budeme v naší kalkulačce potřebovat. Chceme provádět operaci mezi dvěma čísly, což znamená dvojici Text Field komponent a také potřebujeme tlačítko (Button) pro výpočet.

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Také by bylo dobré mít nějakou chytrou volbu pro jednotlivé matematické operace - sčítání, odečítání, násobení a dělení. Pro to se bude hodit komponenta PickerView. Rozmístíme komponenty na připravený View Controller, určitě do horní částí, protože v té spodní bude při zadávání čísel zobrazena klávesnice. Výsledek bude vypadat zhruba takto:

Text Fields a PickerView v Xcode

Pozadí controlleru jsem nastavil na modrou, aby byly zvlášť TextField komponenty vidět. Abychom nemuseli nastavovat constraints pro všechny komponenty, tak využijeme StackView.

StackView

Díky komponentě StackView můžete snadno skládat buď za sebe nebo pod sebe, aniž byste jim museli nastavovat constraints. Zarovnání (ať už na střed nebo přes constraints) pak nastavíte pouze této komponentě.

Kromě vlastnosti Axis, která určuje zda se komponenty skládají vertikálně nebo horizontálně, často využijete Alignment, Distribution a Spacing. První zarovnává, druhá určuje, jak se chovají jinak velké komponenty a poslední určuje mezery mezi komponentami. Ideálně si nyní do StackView vložte několik ovládacích prvků a tyto vlastnosti si proklikejte.

Nejjednodušeji komponenty do StackView "uklidíte" jejich označením a kliknutím na Embed in v constraints menu, které jsme již používali. Potom je nutné vybrat Stack View z nabídky. Po vložení se vám mohou komponenty mírně rozházet, stačí si ale pohrát s nastavením StackView. StackView je také možné přetáhnout z knihovny komponent (zde jako Vertical Stack View a Horizontal Stack View, orientaci ale můžete změnit) a rovnou si vybrat orientaci. Takže jdeme komponenty do StackView uklidit.

Označíme všechny přidané komponenty (pomocí tažení myši nebo třeba pomocí Cmd + levé tlačítko myši v seznamu nalevo) a v menu, kde se nastavují constraints, klikneme na tlačítko Embed in a vybereme Stack View. Tímto vlastně vložíme nový Stack View a rovnou nám do něj Xcode vloží označené komponenty, takže nám ušetří práci. Výsledek je stejný, jako kdybychom Stack View přetáhli z knihovny a komponenty do něj manuálně umístili.

StackView při navrhování kalkulačky v Xcode

Po kliku na Embed in stačí vybrat:

StackView při navrhování kalkulačky v Xcode

Výsledek:

StackView při navrhování kalkulačky v Xcode

Pravděpodobně se vám nyní komponenty poněkud rozhází. O nic nejde, našemu novému StackView nastavíme constraints 0 od levého, horního a pravého okraje.

Dále nastavíme constrains našim TextField komponentám, můžete je pomocí držení Cmd označit obě. Levou a pravou constraint nastavíme např. na 10. Tlačítku nastavíme nějaký text, např. "Calculate". Já změnil ještě barvu textu na bílou kvůli modrému pozadí. Našemu Stack View můžeme nastavit vlastnost Spacing, aby komponenty v něm nebyly tak nalepené na sebe. Uživatelské rozhraní by mělo vypadat zhruba takto:

Dokončené uživatelské rozhraní iOS kalkulačky v Xcode

Zbývá poslední drobnost. Našim TextField nastavíme v Attributes inspektoru vlastnost Keyboard Type na Number Pad, vlastnost najdeme v kategorii Text Input Traits. Tímto se při zadávání rovnou zobrazí klávesnice s čísly.

V Xcode si můžete přepnout náhled pro jednotlivá zařízení a uvidíte, že se naše UI samo přizpůsobuje.

Kód

Tímto naše práce na uživatelském rozhraní končí a přesuneme se do kódu. Otevřete si v Xcode Assistant editor a vytvoříme outlety pro naše TextField komponenty a také pro PickerView, dále action pro stiskutí tlačítka.

@IBOutlet weak var firstNumberInput: UITextField!

@IBOutlet weak var secondNumberInput: UITextField!

@IBOutlet weak var mathOperationPicker: UIPickerView!

@IBAction func calculateBtnClick(_ sender: Any) {

}

Pro PickerView nám nebude stačit action, musíme místo toho nastavit náš controller jako zdroj dat a delegát. K tomu slouží dvojice protokolů, které přidáme.

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

Potom stačí tyto vlastnosti nastavit v metodě viewDidLoad() pomocí self.

override func viewDidLoad() {
        super.viewDidLoad()
        mathOperationPicker.dataSource = self
        mathOperationPicker.delegate = self
}

Tímto vlastně PickerView říkáme, že se náš controller postará o data a celkově bude komponentu obsluhovat.

Nepůjde nám build, musíme totiž implementovat dvojici metod. Xcode nám je pomůže vygenerovat:

func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return 4
}

Protože víme, kolik komponent a řádků budeme mít, můžeme klidně "natvrdo" doplnit počty. Zbývá poslední metoda, která není povinná pro funkční build. Nastavíme, co se vlastně v PickerView má zobrazovat.

let mathOperations = ["+", "-", "*", "/"]

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return mathOperations[row]
}

Aplikaci si můžeme spustit, abychom se přesvědčili, že vše funguje podle očekávání. Design není nejlepší (vlastně je hrozný), ale o ten nám samozřejmě dnes nejde.

Nyní si implementujeme akci tlačítka Calculate pro 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 ještě metoda displayMessage(), která nám zobrazí výsledek v dialogu s tlačítkem pro zavření. Tento způsob jsem zvolil také z důvodu, abychom si ukázali jednoduchou tvorbu dialogu.

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 zkusit něco vypočítat:

Výzva

Jak už jsem zmiňoval na začátku, Autolayout je komplexní a pravděpodobně vás bude ze začátku často otravovat. Zároveň vás ale bude provázet po celou dobu vývoje pro iOS, takže je třeba ho zmáknout.

Ještě než se vrhnete na další lekci, zkuste si vše pořádně procvičit. Vyberte několik svých oblíbených aplikací a zkusíte "zkopírovat" jejich UI ve svém projektu. Stačí umístit komponenty na stejná místa a nastavit constraints. Dole si poté v Xcode změňte náhledové zařízení a přesvědčte se, že vše funguje jak má - komponenty jsou na sprvném místě a nevznikají mezery či další problémy. Komponenty klidně můžete reprezentovat View s různými barvami, jde nám vyloženě o pozice a správné nastavení Autolayout.

Ukažte, že to s vývojem pro iOS myslíte vážně a pochlubte se screenshoty výtvorů níže v komentářích. :-)

Jelikož jsou principy zarovnávání komponent na kontroleru pro tvorbu iOS aplikací velmi klíčové, v příští lekci, Autolayout a StackView - Praktické ukázky, si procvičíme Autolayout a StackView.


 

Stáhnout

Staženo 28x (60 kB)
Aplikace je včetně zdrojových kódů v jazyce Swift

 

 

Článek pro vás napsal Filip Němeček
Avatar
Jak se ti líbí článek?
3 hlasů
Autor se věnuje vývoji iOS aplikací (občas macOS) či těch webových ve frameworku Django. Twitter: @nemecek_f | GitHub nemecek-filip
Předchozí článek
Swift UI pro různé displeje a Autolayout
Všechny články v sekci
Vyvíjíme iOS aplikace ve Swift
Miniatura
Následující článek
Autolayout a StackView - Praktické ukázky
Aktivity (12)

 

 

Komentáře

Avatar
Adam Kudrna
Člen
Avatar
Adam Kudrna:27. března 0:13

Sice tam byly drobné rozdíly, ale už jsem si s nimi poradil a kalkulacka funguje! Díky moc :)

 
Odpovědět 27. března 0:13
Avatar
Filip Němeček
Redaktor
Avatar
Odpovídá na Adam Kudrna
Filip Němeček:27. března 9:57

Ahoj, máš na mysli rozdíly v kódu, které bylo nutné upravit nebo při vytváření uživatelského rozhraní? Jakou máš verzi Xcode? Dík.

 
Odpovědět 27. března 9:57
Avatar
Adam Kudrna
Člen
Avatar
Odpovídá na Filip Němeček
Adam Kudrna:27. března 18:09

Ahoj, mám xcode 10.1. Byly tam malé rozdíly v kódu. Třeba to chtělo napsat tečku v UIAlertContro­ller.Style.aler­t. Ale xcode mi to poradil, takže v pohodě.

 
Odpovědět 27. března 18:09
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Filip Němeček
Redaktor
Avatar
Odpovídá na Adam Kudrna
Filip Němeček:27. března 21:13

Dík za info, já nedávno dělal aktualizaci tutoriálů na Xcode 10 a Swift 4.2, ale tohle mi evidentně uniklo. Při další to opravím :-)

 
Odpovědět 27. března 21:13
Avatar
Adam Kudrna
Člen
Avatar
Odpovídá na Filip Němeček
Adam Kudrna:27. března 22:14

Já moc děkuji za návod. Člověk se při tom i více naučí když hledá chybu :).

 
Odpovědět 27. března 22:14
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 5.