Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

3. diel - Dokončenie jednoduché kalkulačky pre MacOS vo Swift

V predchádzajúcej lekcii, Návrh jednoduchej kalkulačky pre MacOS , sme dokončili užívateľské rozhranie našej jednoduché kalkulačky a zostáva ho uviesť k životu. To znamená, že dnes začneme písať Swift kód. Ešte predtým ale musíme naše komponenty používateľského rozhrania "napojiť" na kód, aby sme k nim mohli pristupovať.

Budeme totiž potrebovať čítať zadané čísla, vybranú operáciu a tiež reagovať na stlačenie tlačidla. No a samozrejme nesmieme zabudnúť na náš Label, ktorý zobrazí výsledok.

Prepojenie UI s kódom

Prepojenie komponentov s kódom funguje na MacOS úplne rovnako ako na iOS, takže pre mnohých z vás určite pôjde iba o opakovanie.

Začneme otvorením Main.storyboard a prepneme na Assistant editor, ktorý zobrazí dva otvorené súbory vedľa seba. Prepínač môžete vidieť nižšie.

Prepínač na Assistant editor v Xcode - Vyvíjame MacOS aplikácie vo Swift

Naľavo by ste mali vidieť naše užívateľské rozhranie a vedľa súbor ViewController.swift, ktorý bude obsluhovať práve naše okno.

Za seba odporúčam označovať komponenty v Document Outline (to je ten zoznam komponentov naľavo od náhľadu používateľského rozhrania). Potom za držanie klávesy Ctrl ťaháme z komponenty do zdrojového súboru, ako je vidieť na animáciu nižšie:

Prepojenie UI komponentov MacOS sa Swift kódom v Xcode - Vyvíjame MacOS aplikácie vo Swift

Týmto vytvoríme tzv. @IBOutlet, čo je špeciálny premenná odkazujúce na našu komponent. Pri spustení programu bude automaticky inicializovaná a môžeme pomocou nej čítať obsah Text Field komponenty a ďalej s ňou manipulovať.

Rovnakým štýlom prepojíme ešte Combo Box, druhý Text Field a posledný Label pre zobrazenie výsledku.

V zdrojovom kóde VC by ste mali mať tieto prepojené komponenty:

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

Moc nepomáha, že v kóde nie sú komponenty Text Field a Label rozlíšené podobne, ako tomu je u iOS. Ich automatické nastavenie ale vybraním v časti s tvorbou UI zaistí, že sa budú správať korektne.

Zostáva tlačidlo. S ním nebudeme pracovať ako s @IBOutlet, ale zaujíma nás iba situácie, keď na neho používateľ klikne. Pre to slúži špeciálne metódy označovanej ako @IBAction a ich vytvorenie je dosť podobné @IBOutlet, stačí zmeniť typ pri vytváraní, pozri opäť animácie nižšie:

Vytvorenie IBaction v Xcode - Vyvíjame MacOS aplikácie vo Swift

A máme hotovú metódu, ktorá bude automaticky spustená pri každom kliknutí na tlačidlo. Práve tu budeme riešiť výpočet a zobrazovať výsledok.

@IBAction func calculateBtnClicked(_ sender: NSButton) {

}

Úpravy storyboard

Ešte, než sa pustíme do implementácie našej výpočtovej metódy, uľahčíme si prácu pomocou jednoduchej úpravy v Main.storyboard. Ako možno viete, náš rodný jazyk používa čiarku na oddelenie desatinnej časti čísla, ale angličtina a programovacie jazyky používajú bodku.

Takže jednoducho našim Text Field komponentom, respektíve ich formátující časti, nastavíme, aby ignorovala lokalizáciu. To v preklade znamená, že bude vždy očakávať bodky v desatinných číslach. Inak nám nedovolí potvrdiť vstup, rovnako ako keby sme napísali písmeno.

V Document Outline je najskôr potrebné rozkliknúť Text Field komponent a dostať sa až na Number Formatter, ako môžete vidieť na screenshote nižšie:

Vybrania Number Formatter v Xcode - Vyvíjame MacOS aplikácie vo Swift

Potom stačí v Attribute inšpektorovi odškrtnúť voľbu "Localizo Format".

Localizo Format v Xcode - Vyvíjame MacOS aplikácie vo Swift

Drobný problém je vyriešený a môžeme sa pustiť do implementácie našej metódy na výpočet. Čo vlastne chceme robiť? V prvom rade potrebujeme zistiť zadané čísla od užívateľa a potom podľa vybranej operácie v komponente Combo Box vykonať výpočet.

Začneme získaním čísel z Text Field komponentov, vďaka Number Formatter by mali byť vždy validný, ale pre istotu využijeme guard a skúsime text z oboch komponentov previesť na čísla. Keď sa to nepodarí, tak skrátka nič ďalšie robiť nebudeme:

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

V tomto kroku už vieme, že máme k dispozícii dve čísla a môžeme vykonať výpočet. Z Combo Box možno jednoducho získať index zvoleného prvku, takže využijeme jednoduchý switch a rovno výsledok nastavíme ako stringValue našej Label komponente pre zobrazenie 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 = "-"
}

Teraz môžete aplikáciu zapnúť a bude počítať. Pre istotu si ukážeme kompletnú metódu pre tlačidlo:

@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ša kalkulačka má jeden drobný problém, v Combo Box nie je po zapnutí nič vybrané. To môžeme vyriešiť jedným riadkom kódu v metóde viewDidLoad(), ktorá je zavolaná po spustení aplikácie.

Tu jednoducho vyberieme treba prvú operáciu:

override func viewDidLoad() {
        super.viewDidLoad()

        mathOperationComboBox.selectItem(at: 0)
}

Ak vám vadí, že sa aplikácia pri skúšaní nezavrie pri zatvorení okna, existuje na to rýchla oprava. Otvorte si AppDelegate.swift a pridajte túto metódu. Xcode vám ju prípadne napovie:

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

Jej názov jednoznačne vystihuje, o čo vlastne ide. Keď používateľ zavrie posledný okno (v našom prípade jedinej), dôjde tiež k vypnutiu aplikácie.

Dialóg

Možno vás napadlo, čo sa stane, keď sa používateľ pokúsi deliť 0 ? Aplikácia prekvapivo nespadne, ale zobrazí výsledok "inf" ako infinity čiže nekonečno. Keby sme ako dátový typ používali Int miesto Float, tak aplikácia spadne.

Ani jedno nie je ideálne, takže si ukážeme riešenia a rovno tiež, ako zobraziť informačný dialóg užívateľmi.

Pripravíme si metódu, ktorá zobrazí tento dialóg a informuje užívateľa, že deliť 0 jednoducho nejde:

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

Zobrazenie základného dialógu je veľmi jednoduché. Stačí vytvoriť inštanciu NSAlert a pridať text. Potom už len stačí dialóg zobraziť. Bude vyzerať takto:

Swift dialóg pre delenie nulou v MacOS - Vyvíjame MacOS aplikácie vo Swift

Zostáva teda vyriešiť situáciu, keď sa používateľ pokúsi deliť 0. Upravíme teda náš switch v metóde obsluhujúci tlačidlo, konkrétne prípad, keď je vybrané delenie. Pred samotnej delenie umiestnime podmienku, kde sa jednoducho spýtame, či náhodou nie je druhé číslo 0. Ak áno, tak zobrazíme dialóg a ďalej nepokračujeme:

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

A to je celé! Máme prvý funkčný MacOS aplikáciu.

MacOS kalkulačka vo Swift - Vyvíjame MacOS aplikácie vo Swift

V budúcej lekcii, PRIPOMIENKOVÉ narodenín pre MacOS - Príprava UI , začneme už komplexnejšie projekt, na ktorom sa naučíme používať ďalšie ovládacie prvky.


 

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é 18x (38.85 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Swift

 

Predchádzajúci článok
Návrh jednoduchej kalkulačky pre MacOS
Všetky články v sekcii
Vyvíjame MacOS aplikácie vo Swift
Preskočiť článok
(neodporúčame)
PRIPOMIENKOVÉ narodenín pre MacOS - Príprava UI
Článok pre vás napísal Filip Němeček
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje vývoji iOS aplikací (občas macOS)
Aktivity