IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

5. diel - PRIPOMIENKOVÉ narodenín pre MacOS - Dokončenie UI a prepojenie

V minulej lekcii, PRIPOMIENKOVÉ narodenín pre MacOS - Príprava UI , sme si vytvorili hlavné okno aplikácie a prepojili UI komponenty s kódom. Tým ale naša tvorba užívateľského rozhrania neskončila, pretože ešte potrebujeme druhé okno, kde bude užívateľ môcť osoby pridávať. Okno bude jednoduchšie, pretože nám bude stačiť iba zadať meno a pomocou špecializované komponenty vybrať dátum narodenia.

Okno pre pridanie osoby

Najskôr si teda vytvoríme druhé okno.

Vytvorenie modálneho okná

Otvoríme Main.storyboard az knižnice komponentov pretiahneme Window Controller. Týmto vlastne získame to isté, čo sme mali pri vytvorení projektu, teda okno a na neho naviazaný View Controller.

Mali by sme získať zhruba niečo takéto:

Nové okno MacOS aplikácie v Xcode - Vyvíjame MacOS aplikácie vo Swift

Pre väčšiu prehľadnosť upravíme oknám titulky. Prvému oknu nastavíme titulok "BirthdayMinder" podľa názvu projektu, túto vlastnosť Title nájdete v Attributes inšpektorovi.

Vyvíjame MacOS aplikácie vo Swift

U druhého okna musíme upraviť Title, avšak u View Controlleru, pretože budeme druhé okno zobrazovať druhov dopravy štýlom, teda ako dialóg. Tu ako Title nastavíme "Pridať osobu".

Otvorenie modálneho okna

Ešte, než na druhé okno zasadíte nejaký ovocný komponenty, pripravíme si navigáciu, aby sme sa na neho vôbec mohli dostať. Možností je viac, my sa spoľahneme na jednoduché segue, podobne ako u iOS aplikácií.

Segue vytvoríme v Main.storyboard pomocou ťahanie za držanie Ctrl z View Controlleru prvého okna (toho hlavného) na View Controller druhého okna. Odporúčam ťaženie vykonávať v Document outline (teda v zozname komponentov v ľavej časti), aby ste mali istotu, že skutočne ťaháte z View Controller.

Z ponuky vyberieme možnosť "Modal", ktorá spôsobí, že nové okno bude dočasne hlavným oknom aplikácie a na to prvé nepôjde do zatvorenia nového okna kliknúť. Tým dáme užívateľovi najavo, že musí dokončiť prácu s druhým oknom, aby mohol pokračovať. Postup pre vytvorenie segue si ukážme na animáciu:

Postup pre vytvorenie segue pre navigáciu medzi oknami aplikácie - Vyvíjame MacOS aplikácie vo Swift

Ak by ste chceli mať jednoducho len viac okien a užívateľa neobmedzovať, stačilo by zvoliť možnosť "Show".

Teraz potrebujeme vytvorené segue pomenovať, pretože s ním budeme pracovať v kóde. Nové segue teda označíme a v Attributes inšpektorovi mu nastavíme vlastnosť Identifier na "AddPersonSegue".

Vyvíjame MacOS aplikácie vo Swift

Segue by bolo možné vytvoriť ťahaním priamo z tlačidla "Pridať" na druhý View Controller, čím by toto tlačidlo automaticky nové okno otvorilo. Manuálne spustenie segue je ale flexibilnejší, preto ho použijeme.

Dostávame sa do finále a konečne si okno otvoríme. Postačí k tomu jeden riadok kódu. Otvoríme si ViewController.swift a do metódy addBtn_Clicked(), ktorá slúži k obsluhe tlačidla Pridať, doplníme nasledujúci kód:

performSegue(withIdentifier: "AddPersonSegue", sender: self)

Aplikáciu môžeme spustiť a vyskúšať:

Modálne dialóg v MacOS a Swift - Vyvíjame MacOS aplikácie vo Swift

Bohužiaľ okno sa nezobrazuje relatívne vzhľadom k tomu hlavnému. To nie je niečo, čo by sa dalo v Main.storyboard ľahko naklikať, riešenie pomocou kódu si ukážeme neskôr.

Tvorba UI modálneho okna

Prázdne okno je nám celkom k ničomu, preto ho naplníme komponentmi. Budeme potrebovať textové pole pre zadanie mena osoby, špeciálne komponent Date Picker pre výber dátumu narodenia a tlačidlo pre potvrdenie.

Zatváranie okná riešiť nebudeme, k tomu má užívateľ systémové tlačidlo. Ako bonus pridáme dvojicu Label komponentov, aby používateľ vedel, čo má zadať a vybrať. A konečne ešte pridáme obrázok, ktorý sa bude meniť podľa nastaveného farebného téme MacOS, ktorá systém podporuje od verzie Mojave.

Push Button

Trochu netradične začneme odspodu a pridáme Push Button. Pomocou AutoLayout mu nastavíme horizontálne zarovnanie a trebárs 15 bodov od spodného okraja okna. Ešte nastavíme fixné šírku na 80 a nastavíme text "Pridať". Celkovo tak máme tri constraints.

Hodí sa povedať, že práve táto tvorba UI je skôr odporúčania. Ak chcete experimentovať a máte lepší nápad, ako komponenty poskladať, tak určite smelo do toho :-)

Date Picker

Nad tlačidlo pretiahneme z knižnice komponent Date Picker. Opäť ju zarovnáme horizontálne na stred a nastavíme spodné CONSTRAINT na 15 bodov, teda na 15 bodov od predtým pridaného tlačidla. Predvolené nastavenie komponenty nám vyhovuje a nič nie je potrebné meniť.

Text Field

Posledný z nutných komponentov je Text Field, ktorý bude slúžiť na vyplnenie mena osoby. Opäť mu nastavíme zarovnanie na horizontálne stred, 15 bodov od spodnej hrany a fixné šírku 90.

Aktuálne UI vyzerá zhruba takto:

Modálne okno pre zadanie novej osoby vo Swift - Vyvíjame MacOS aplikácie vo Swift

Labely

Pridáme Label komponenty, aby sme používateľovi pripomenuli, čo má zadať. Komponentom nastavíme veľkosť fontu System Small a zarovnáme vertikálne s komponentom, ku ktorej patrí.

Zarovnanie labelu s komponentom v MacOS aplikácii v Xcode - Vyvíjame MacOS aplikácie vo Swift

Potom už bude stačiť nastaviť len odsadenie z pravej strany. Ja som zvolil hodnotu 3. To isté vykonáme pre Label patriaci k Date Picker.

Obrázky pre svetlé i tmavé tému MacOS

Ako asi viete, MacOS od verzie Mojave ponúka možnosť zapnúť tmavé tému. A ak si nenastavíte vlastné farby komponentov, bude aplikácia vyzerať dobre v oboch prípadoch. Na tej našej to môžeme vyskúšať. Stačí v Xcode prepnúť "View as: Dark Appearance" na svetlé tému.

Aplikácia pre MacOS v svetlom téme - Vyvíjame MacOS aplikácie vo Swift

My chceme naše okno pre pridanie novej osoby doplniť obrázkom. Pretože sa jedná o jednofarebný obrázok, tak chceme, aby aplikácie pre každú tému použila iný. To sa dá veľmi ľahko zariadiť. Obe varianty obrázku nájdete v zdrojových súboroch k tejto lekcii.

Image Set

V prvom rade si otvoríme Assets.xcassets a pomocou tlačidla + dole pridáme New Image Set. Ten z východzieho Image premenujeme na Person. Otvoríme si Attributes inšpektor tohto obrázku a nájdeme položku Apperances. Tá je v predvolenom stave nastavená na None. My vyberieme možnosť Any, Dark.

Hneď môžeme vidieť, že sa zmenili "kolónky" pre obrázky a máme možnosť pridať obrázok pre tmavé tému:

Kolónky pre pridanie obrázkov - Vyvíjame MacOS aplikácie vo Swift

Zostáva presunúť obrázky:

Obrázok v kolónkach pre pridanie obrázkov - Vyvíjame MacOS aplikácie vo Swift

A to je všetko! Teraz už stačí tento obrázok použiť a systém automaticky vyberie správny podľa nastaveného témy.

Vrátime sa do Main.storyboard a dokončíme druhé okno.

Image View

Pridáme komponent Image View pre zobrazovanie obrázkov a rovno ju ako obrázok nastavíme Person, ktorý sme si pripravili. Stačí nastaviť AutoLayout a bude hotovo.

Image View tradične zarovnáme horizontálne na stred, nastavíme vzdialenosť 20 od hornej hrany, minimálne 15 od spodnej hrany (teda od textového poľa) a maximálnu výšku na 150. Opäť platí, že sa jedná o návrhy a môžete samozrejme experimentovať.

Constraints pre obrázok vyzerajú takto:

Constraints pre MacOS obrázok v Xcode - Vyvíjame MacOS aplikácie vo Swift

A hotové druhé okno aplikácie:

Dokončené modálne okno - Vyvíjame MacOS aplikácie vo Swift

Môžeme tiež vyskúšať, že fungujú správne obrázky:

Prepínanie motívu MacOS aplikácie v Xcode - Vyvíjame MacOS aplikácie vo Swift

Prepojenie UI a kódu

Užívateľské rozhranie druhého okna je hotové, teraz ho prepojíme s kódom. Potrebujeme @IBOutlet pre Text Field a Date Picker. Pre tlačidlo Pridať vytvoríme @IBAction. Jedná sa o opakovanie, v AddPersonViewController by sme mali mať:

@IBOutlet var nameTextField: NSTextField!
@IBOutlet var datePicker: NSDatePicker!

@IBAction func confirmBtn_Clicked(_ sender: NSButton) {
}

Komunikácia medzi oknami

Na záver tejto lekcie si obe okná prepojíme, aby sme v tej ďalšej mohli pohodlne začať pridávať osoby.

Prvým krokom je vytvorenie View Controlleru pre druhé okno. Nezabudnite pri vytváraní súboru vybrať Cocoa Class a na ďalšej obrazovke nastaviť ako subclass NSViewController. Išlo by to aj ručne, ale tento spôsob je rýchlejší. Ako názov zvolíme AddPersonViewController. Pred potvrdením skontrolujte, že nie je zaškrtnutá možnosť "Also create XIB file for user interface". To nechceme.

Teraz musíme do Main.storyboard a nastaviť novovytvorenú triedu druhému View Controlleru v jeho Identity inšpektorovi:

Identity inspector druhého View Controlleru - Vyvíjame MacOS aplikácie vo Swift

Vrátime sa do AddPersonViewController a pridáme si nasledujúce vlastnosť:

weak var delegateVC: ViewController!

Možností, ako komunikovať medzi oknami, je nespočet. My si ukážeme jednoduchú z nich, inšpirovanú návrhovým vzorom delegát. Pomocou tejto vlastnosti získame prístup k View Controlleru hlavného okna a budeme ho môcť informovať o tom, že používateľ vyplnil údaje a chce pridať osobu. Samozrejme by sme tu mohli využiť protokol, ale my tvoríme jednoduchú aplikáciu.

Vlastnosť musí byť weak, aby medzi oboma View Controllery nevznikol retain cycle, kedy sa objekty vlastné navzájom a nemôže preto dôjsť k ich delokácia.

Vrátime sa do ViewController a preťažíme metódu prepare(), ktorá je automaticky zavolaná tesne predtým, než prebehne segue.

Jej kostra vyzerá takto:

override func prepare(for segue: NSStoryboardSegue, sender: Any?) {

}

Tu zistíme, či ide o "AddPersonSegue" a ak áno, tak z neho získame cieľový View Controller, čo bude práve náš AddPersonViewController a nastavíme mu vlastnosť delegateVC, čím oba controllery prepojíme:

override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
        if segue.identifier == "AddPersonSegue" {
            let addPersonVC = segue.destinationController as! AddPersonViewController
            addPersonVC.delegateVC = self
        }
}

Vieme, akého typu má byť destinationController, takže použitie as! je v poriadku a dáva zmysel. Potom už len nastavíme vlastnosť delegateVC.

Nášmu ViewController ešte pridáme nasledujúce metódu, aby sme mohli prepojenie ľahko otestovať:

func addPerson(name: String) {
        print("Adding: \(name)")
}

Zostáva zamieriť do AddPersonViewController a doplniť provizórne kód tlačidla Pridať:

@IBAction func confirmBtn_Clicked(_ sender: NSButton) {
        delegateVC.addPerson(name: "Test")
}

Aplikáciu môžete zapnúť a skontrolovať výpis konzoly v Xcode. Pomocou addPerson() metódy neskôr budeme osoby pridávať už naozaj.

Oprava pozície druhého okna

Na úplný záver si opravíme štartovaciu pozíciu druhého okna, ako máme sľúbené. Využijeme na to preťaženú metódu viewDidAppear(). Nemôžeme použiť viewDidLoad(), pretože v tomto štádiu ešte nie je plne inicializovanej okno (aj keď k tomu názov zvádza) a nedostali by sme sa k nemu.

Pre istotu nezabudneme tiež zavolať super.viewDidAppear().

Základná kostra metódy v AddPersonViewController teda vyzerá takto:

override func viewDidAppear() {
        super.viewDidAppear()
}

Čo vlastne potrebujeme urobiť?

Najskôr získať pozíciu prvého okna, získať rámček druhého okna (kvôli rozmerom), vypočítať korektné pozíciu a nastaviť ju druhému oknu. Celá metóda bude vyzerať takto:

override func viewDidAppear() {
        super.viewDidAppear()
        let mainWindowFrame = delegateVC.view.window!.frame
        let addPersonFrame = view.window!.frame
        let yPosition = mainWindowFrame.midY - addPersonFrame.height / 2
        let xPosition = mainWindowFrame.midX - addPersonFrame.width / 2
        view.window!.setFrameOrigin(CGPoint(x: xPosition, y: yPosition))
}

MacOS počíta pozície od ľavého dolného rohu, zatiaľ čo iOS (v UIKit) od ľavého horného.

Pre korektné pozíciu teda zistíme strednej Y a X súradnice a od každej odpočítame polovicu šírky respektíve výšky, čím získame korektné pozíciu pre druhé okno.

Môžeme vyskúšať:

Otvorenie dialógového okna na stred v MacOS a Swift - Vyvíjame MacOS aplikácie vo Swift

Týmto sme úspešne dokončili celé UI, prepojili okná medzi sebou a tiež sme vyriešili pozicovanie druhého okna. V nasledujúcej lekcii, PRIPOMIENKOVÉ narodenín pre MacOS - Table View a práca s dátumom , sprevádzkujeme pridávanie osôb a oživíme Table View.


 

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

 

Predchádzajúci článok
PRIPOMIENKOVÉ narodenín pre MacOS - Príprava UI
Všetky články v sekcii
Vyvíjame MacOS aplikácie vo Swift
Preskočiť článok
(neodporúčame)
PRIPOMIENKOVÉ narodenín pre MacOS - Table View a práca s dátumom
Č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