PHP týden Body zdarma
Pouze tento týden sleva až 80 % na PHP e-learning
Využij podzimních slev a získej od nás až 40 % bodů zdarma! Více zde

Lekce 3 - Dokončení jednoduché kalkulačky pro macOS 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.

V předchozí lekci, Návrh jednoduché kalkulačky pro macOS, jsme dokončili uživatelské rozhraní naší jednoduché kalkulačky a zbývá ho uvést k životu. To znamená, že dnes začneme psát Swift kód. Ještě předtím ale musíme naše komponenty uživatelského rozhraní "napojit" na kód, abychom k nim mohli přistupovat.

Budeme totiž potřebovat číst zadaná čísla, vybranou operaci a také reagovat na stisk tlačítka. No a samozřejmě nesmíme zapomenout na náš Label, který zobrazí výsledek.

Propojení UI s kódem

Propojení komponent s kódem funguje na macOS úplně stejně jako na iOS, takže pro mnohé z vás určitě půjde pouze o opakování.

Začneme otevřením Main.storyboard a přepneme na Assistant editor, který zobrazí dva otevřené soubory vedle sebe. Přepínač můžete vidět níže.

Přepínač na Assistant editor v Xcode

Nalevo byste měli vidět naše uživatelské rozhraní a vedle soubor ViewController.swift, který bude obsluhovat právě naše okno.

Za sebe doporučuji označovat komponenty v Document Outline (to je ten seznam komponent nalevo od náhledu uživatelského rozhraní). Potom za držení klávesy Ctrl táhneme z komponenty do zdrojového souboru, jak je vidět na animaci níže:

Propojení UI komponent macOS se Swift kódem v Xcode

Tímto vytvoříme tzv. @IBOutlet, což je speciální proměnná odkazující na naši komponentu. Při spuštění aplikace bude automaticky inicializovaná a můžeme pomocí ní číst obsah Text Field komponenty a dále s ní manipulovat.

Stejným stylem propojíme ještě Combo Box, druhý Text Field a poslední Label pro zobrazení výsledku.

Ve zdrojovém kódu VC byste měli mít tyto propojené komponenty:

@IBOutlet var firstInput: NSTextField!
@IBOutlet var secondInput: NSTextField!
@IBOutlet var mathOperationComboBox: NSComboBox!
@IBOutlet var resultsLabel: NSTextField!

Moc nepomáhá, že v kódu nejsou komponenty Text Field a Label rozlišeny podobně, jako tomu je u iOS. Jejich automatické nastavení ale vybráním v části s tvorbou UI zajistí, že se budou chovat korektně.

Zbývá tlačítko. S ním nebudeme pracovat jako s @IBOutlet, ale zajímá nás pouze situace, kdy na něj uživatel klikne. Pro to slouží speciální metody označované jako @IBAction a jejich vytvoření je dost podobné @IBOutlet, stačí změnit typ při vytváření, viz opět animace níže:

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

A máme hotovou metodu, která bude automaticky spuštěna při každém kliknutí na tlačítko. Právě zde budeme řešit výpočet a zobrazovat výsledek.

@IBAction func calculateBtnClicked(_ sender: NSButton) {

}

Úpravy storyboard

Ještě, než se pustíme do implementace naší výpočetní metody, usnadníme si práci pomocí jednoduché úpravy v Main.storyboard. Jak možná víte, náš rodný jazyk používá čárku k oddělení desetinné části čísla, ale angličtina a programovací jazyky používají tečku.

Takže jednoduše našim Text Field komponentám, respektive jejich formátující části, nastavíme, aby ignorovala lokalizaci. To v překladu znamená, že bude vždy očekávat tečky v desetinných číslech. Jinak nám nedovolí potvrdit vstup, stejně jako kdybychom napsali písmeno.

V Document Outline je nejdříve třeba rozkliknout Text Field komponentu a dostat se až na Number Formatter, jak můžete vidět na screenshotu níže:

Vybrání Number Formatter v Xcode

Potom stačí v Attribute inspektoru odškrtnout volbu "Localize Format".

Localize Format v Xcode

Drobný problém je vyřešen a můžeme se pustit do implementace naší metody na výpočet. Co vlastně chceme dělat? V první řadě potřebujeme zjistit zadaná čísla od uživatele a potom podle vybrané operace v komponentě Combo Box provést výpočet.

Začneme získáním čísel z Text Field komponent, díky Number Formatter by měly být vždy validní, ale pro jistotu využijeme guard a zkusíme text z obou komponent převést na čísla. Když se to nepovede, tak zkrátka nic dalšího dělat nebudeme:

guard let firstNumber = Float(firstInput.stringValue),
    let secondNumber = Float(secondInput.stringValue) else {return}

V tomto kroku již víme, že máme k dispozici dvě čísla a můžeme provést výpočet. Z Combo Box lze jednoduše získat index zvoleného prvku, takže využijeme jednoduchý switch a rovnou výsledek nastavíme jako stringValue naší Label komponentě pro zobrazení výsledku:

switch mathOperationComboBox.indexOfSelectedItem {
        case 0:
            resultsLabel.stringValue = "\(firstNumber + secondNumber)"
        case 1:
            resultsLabel.stringValue = "\(firstNumber - secondNumber)"
        case 2:
            resultsLabel.stringValue = "\(firstNumber / secondNumber)"
        case 3:
            resultsLabel.stringValue = "\(firstNumber * secondNumber)"
        default:
            resultsLabel.stringValue = "-"
}

Nyní můžete aplikaci zapnout a bude počítat. Pro jistotu si ukážeme kompletní metodu pro tlačítko:

@IBAction func calculateBtnClicked(_ sender: NSButton) {
        guard let firstNumber = Float(firstInput.stringValue),
            let secondNumber = Float(secondInput.stringValue) else {return}

        switch mathOperationComboBox.indexOfSelectedItem {
        case 0:
            resultsLabel.stringValue = "\(firstNumber + secondNumber)"
        case 1:
            resultsLabel.stringValue = "\(firstNumber - secondNumber)"
        case 2:
            resultsLabel.stringValue = "\(firstNumber / secondNumber)"
        case 3:
            resultsLabel.stringValue = "\(firstNumber * secondNumber)"
        default:
            resultsLabel.stringValue = "-"
        }
}

Naše kalkulačka má jeden drobný problém, v Combo Box není po zapnutí nic vybrané. To můžeme vyřešit jedním řádkem kódu v metodě viewDidLoad(), která je zavolána po spuštění aplikace.

Zde jednoduše vybereme třeba první operaci:

override func viewDidLoad() {
        super.viewDidLoad()

        mathOperationComboBox.selectItem(at: 0)
}

Jestli vám vadí, že se aplikace při zkoušení nezavře při zavření okna, existuje na to rychlá oprava. Otevřete si AppDelegate.swift a přidejte tuto metodu. Xcode vám ji případně napoví:

func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
        return true
}

Její název jednoznačně vystihuje, o co vlastně jde. Jakmile uživatel zavře poslední okno (v našem případě jediné), dojde také k vypnutí aplikace.

Dialog

Možná vás napadlo, co se stane, když se uživatel pokusí dělit 0? Aplikace překvapivě nespadne, ale zobrazí výsledek "inf" jako infinity neboli nekonečno. Kdybychom jako datový typ používali Int místo Float, tak aplikace spadne.

Ani jedno není ideální, takže si ukážeme řešení a rovnou také, jak zobrazit informační dialog uživateli.

Připravíme si metodu, která zobrazí tento dialog a informuje uživatele, že dělit 0 prostě nejde:

func showDivisionByZeroAlert() {
        let alert = NSAlert()
        alert.messageText = "Even this cool app cannot divide by 0!"
        alert.runModal()
}

Zobrazení základního dialogu je velmi snadné. Stačí vytvořit instanci NSAlert a přidat text. Potom už pouze stačí dialog zobrazit. Bude vypadat takto:

Swift dialog pro dělení nulou v macOS

Zbývá tedy vyřešit situaci, kdy se uživatel pokusí dělit 0. Upravíme tedy náš switch v metodě obsluhující tlačítko, konkrétně případ, kdy je vybráno dělení. Před samotné dělení umístíme podmínku, kde se jednoduše zeptáme, jestli náhodou není druhé číslo 0. Pokud ano, tak zobrazíme dialog a dál nepokračujeme:

case 2:
            if secondNumber == 0 {
                showDivisionByZeroAlert()
                return
            }
            resultsLabel.stringValue = "\(firstNumber / secondNumber)"

A to je celé! Máme první funkční macOS aplikaci.

macOS kalkulačka ve Swift

V příští lekci, Upomínač narozenin pro macOS - Příprava UI, započneme již komplexnější projekt, na kterém se naučíme používat další ovládací prvky.


 

Stáhnout

Staženo 6x (38.85 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?
Ještě nikdo nehodnotil, buď první!
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
Návrh jednoduché kalkulačky pro macOS
Všechny články v sekci
Vyvíjíme macOS aplikace ve Swift
Miniatura
Následující článek
Upomínač narozenin pro macOS - Příprava UI
Aktivity (3)

 

 

Komentáře

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.

Zatím nikdo nevložil komentář - buď první!