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

Lekce 5 - Upomínač narozenin pro macOS - Dokončení UI a propojení

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 minulé lekci, Upomínač narozenin pro macOS - Příprava UI, jsme si vytvořili hlavní okno aplikace a propojili UI komponenty s kódem. Tím ale naše tvorba uživatelského rozhraní neskončila, protože ještě potřebujeme druhé okno, kde bude uživatel moci osoby přidávat. Okno bude jednodušší, protože nám bude stačit pouze zadat jméno a pomocí specializované komponenty vybrat datum narození.

Okno pro přidání osoby

Nejdříve si tedy vytvoříme druhé okno.

Vytvoření modálního okna

Otevřeme Main.storyboard a z knihovny komponent přetáhneme Window Controller. Tímto vlastně získáme to samé, co jsme měli při vytvoření projektu, tedy okno a na něj navázaný View Controller.

Měli bychom získat zhruba něco takového:

Nové okno macOS aplikace v Xcode

Pro větší přehlednost upravíme oknům titulky. Prvnímu oknu nastavíme titulek "BirthdayMinder" podle názvu projektu, tuto vlastnost Title naleznete v Attributes inspektoru.

U druhého okna musíme upravit Title, ovšem u View Controlleru, protože budeme druhé okno zobrazovat modálním stylem, tedy jako dialog. Zde jako Title nastavíme "Přidat osobu".

Otevření modálního okna

Ještě, než na druhé okno nasázíme komponenty, připravíme si navigaci, abychom se na něj vůbec mohli dostat. Možností je více, my se spolehneme na jednoduché segue, podobně jako u iOS aplikací.

Segue vytvoříme v Main.storyboard pomocí tažení za držení Ctrl z View Controlleru prvního okna (toho hlavního) na View Controller druhého okna. Doporučuji tažení provádět v Document outline (tedy v seznamu komponent v levé části), abyste měli jistotu, že skutečně táhnete z View Controller.

Z nabídky vybereme možnost "Modal", která způsobí, že nové okno bude dočasně hlavním oknem aplikace a na to první nepůjde do zavření nového okna kliknout. Tím dáme uživateli najevo, že musí dokončit práci s druhým oknem, aby mohl pokračovat. Postup pro vytvoření segue si ukažme na animaci:

Postup pro vytvoření segue pro navigaci mezi okny aplikace

Pokud byste chtěli mít jednoduše jen více oken a uživatele neomezovat, stačilo by zvolit možnost "Show".

Nyní potřebujeme vytvořené segue pojmenovat, protože s ním budeme pracovat v kódu. Nové segue tedy označíme a v Attributes inspektoru mu nastavíme vlastnost Identifier na "AddPersonSegue".

Segue by bylo možné vytvořit tažením přímo z tlačítka "Přidat" na druhý View Controller, čímž by toto tlačítko automaticky nové okno otevřelo. Manuální spuštění segue je ale flexibilnější, proto ho použijeme.

Dostáváme se do finále a konečně si okno otevřeme. Postačí k tomu jeden řádek kódu. Otevřeme si ViewController.swift a do metody addBtn_Clicked(), která slouží k obsluze tlačítka Přidat, doplníme následující kód:

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

Aplikaci můžeme spustit a vyzkoušet:

Modální dialog v macOS a Swift

Bohužel okno se nezobrazuje relativně vzhledem k tomu hlavnímu. To není něco, co by se dalo v Main.storyboard snadno naklikat, řešení pomocí kódu si ukážeme později.

Tvorba UI modálního okna

Prázdné okno je nám celkem k ničemu, proto jej naplníme komponentami. Budeme potřebovat textové pole pro zadání jména osoby, speciální komponentu Date Picker pro výběr data narození a tlačítko pro potvrzení.

Zavírání okna řešit nebudeme, k tomu má uživatel systémové tlačítko. Jako bonus přidáme dvojici Label komponent, aby uživatel věděl, co má zadat a vybrat. A konečně ještě přidáme obrázek, který se bude měnit podle nastaveného barevného tématu macOS, která systém podporuje od verze Mojave.

Push Button

Trochu netradičně začneme odspodu a přidáme Push Button. Pomocí AutoLayout mu nastavíme horizontální zarovnání a třeba 15 bodů od spodního okraje okna. Ještě nastavíme fixní šířku na 80 a nastavíme text "Přidat". Celkem tak máme tři constraints.

Hodí se říci, že zrovna tato tvorba UI je spíše doporučení. Jestli chcete experimentovat a máte lepší nápad, jak komponenty poskládat, tak určitě směle do toho :-)

Date Picker

Nad tlačítko přetáhneme z knihovny komponentu Date Picker. Opět ji zarovnáme horizontálně na střed a nastavíme spodní constraint na 15 bodů, tedy na 15 bodů od dříve přidaného tlačítka. Výchozí nastavení komponenty nám vyhovuje a nic není třeba měnit.

Text Field

Poslední z nutných komponent je Text Field, který bude sloužit k vyplnění jména osoby. Opět mu nastavíme zarovnání na horizontální střed, 15 bodů od spodní hrany a fixní šířku 90.

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

Aktuální UI vypadá zhruba takto:

Modální okno pro zadání nové osoby ve Swift

Labely

Přidáme Label komponenty, abychom uživateli připomněli, co má zadat. Komponentám nastavíme velikost fontu System Small a zarovnáme vertikálně s komponentou, ke které patří.

Zarovnání labelu s komponentou v macOS aplikaci v Xcode

Potom již bude stačit nastavit jen odsazení z pravé strany. Já jsem zvolil hodnotu 3. To samé provedeme pro Label patřící k Date Picker.

Obrázky pro světlé i tmavé téma macOS

Jak asi víte, macOS od verze Mojave nabízí možnost zapnout tmavé téma. A pokud si nenastavíme vlastní barvy komponent, bude aplikace vypadat dobře v obou případech. Na té naší to můžeme vyzkoušet. Stačí v Xcode přepnout "View as: Dark Appearance" na světlé téma.

Aplikace pro macOS ve světlém tématu

My chceme naše okno pro přidání nové osoby doplnit obrázkem. Protože se jedná o jednobarevný obrázek, tak chceme, aby aplikace pro každé téma použila jiný. To se dá velmi snadno zařídit. Obě varianty obrázku najdete ve zdrojových souborech k této lekci.

Image Set

V první řadě si otevřeme Assets.xcassets a pomocí tlačítka + dole přidáme New Image Set. Ten z výchozího Image přejmenujeme na Person. Otevřeme si Attributes inspektor tohoto obrázku a najdeme položku Apperances. Ta je ve výchozím stavu nastavena na None. My vybereme možnost Any, Dark.

Hned můžeme vidět, že se změnily "kolonky" pro obrázky a máme možnost přidat obrázek pro tmavé téma:

Kolonky pro přidání obrázků

Zbývá přesunout obrázky:

Obrázek v kolonkách pro přidání obrázků

A to je vše! Nyní již stačí tento obrázek použít a systém automaticky vybere správný podle nastaveného tématu.

Vrátíme se do Main.storyboard a dokončíme druhé okno.

Image View

Přidáme komponentu Image View pro zobrazování obrázků a rovnou ji jako obrázek nastavíme Person, který jsme si připravili. Stačí nastavit AutoLayout a bude hotovo.

Image View tradičně zarovnáme horizontálně na střed, nastavíme vzdálenost 20 od horní hrany, minimálně 15 od spodní hrany (tedy od textového pole) a maximální výšku na 150. Opět platí, že se jedná o návrhy a můžete samozřejmě experimentovat.

Constraints pro obrázek vypadají takto:

Constraints pro macOS obrázek v Xcode

A hotové druhé okno aplikace:

Dokončené modální okno

Můžeme také vyzkoušet, že fungují správné obrázky:

Přepínání motivu macOS aplikace v Xcode

Propojení UI a kódu

Uživatelské rozhraní druhého okna je hotové, nyní ho propojíme s kódem. Potřebujeme @IBOutlet pro Text Field a Date Picker. Pro tlačítko Přidat vytvoříme @IBAction. Jedná se o opakování, v AddPersonViewController bychom měli mít:

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

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

Komunikace mezi okny

Na závěr této lekce si obě okna propojíme, abychom v té další mohli pohodlně začít přidávat osoby.

Prvním krokem je vytvoření View Controlleru pro druhé okno. Nezapomeňte při vytváření souboru vybrat Cocoa Class a na další obrazovce nastavit jako subclass NSViewController. Šlo by to i ručně, ale tento způsob je rychlejší. Jako název zvolíme AddPersonViewController. Před potvrzením zkontrolujte, že není zaškrtnuta možnost "Also create XIB file for user interface". To nechceme.

Nyní musíme do Main.storyboard a nastavit nově vytvořenou třídu druhému View Controlleru v jeho Identity inspektoru:

Identity inspector druhého View Controlleru

Vrátíme se do AddPersonViewController a přidáme si následující vlastnost:

weak var delegateVC: ViewController!

Možností, jak komunikovat mezi okny, je nespočet. My si ukážeme jednoduchou z nich, inspirovanou návrhovým vzorem delegát. Pomocí této vlastnosti získáme přístup k View Controlleru hlavního okna a budeme ho moci informovat o tom, že uživatel vyplnil údaje a chce přidat osobu. Samozřejmě bychom zde mohli využít protokol, ale my tvoříme jednoduchou aplikaci.

Vlastnost musí být weak, aby mezi oběma View Controllery nevznikl retain cycle, kdy se objekty vlastní navzájem a nemůže proto dojít k jejich dealokaci.

Vrátíme se do ViewController a přetížíme metodu prepare(), která je automaticky zavolána těsně předtím, než proběhne segue.

Její kostra vypadá takto:

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

}

Zde zjistíme, jestli jde o "AddPersonSegue" a pokud ano, tak z něj získáme cílový View Controller, což bude právě náš AddPersonViewController a nastavíme mu vlastnost delegateVC, čímž oba controllery propojíme:

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

Víme, jakého typu má být destinationController, takže použití as! je v pořádku a dává smysl. Pak už jen nastavíme vlastnost delegateVC.

Našemu ViewController ještě přidáme následující metodu, abychom mohli propojení snadno otestovat:

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

Zbývá zamířit do AddPersonViewController a doplnit provizorní kód tlačítka Přidat:

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

Aplikaci můžete zapnout a zkontrolovat výpis konzole v Xcode. Pomocí addPerson() metody později budeme osoby přidávat již doopravdy.

Oprava pozice druhého okna

Na úplný závěr si opravíme startovní pozici druhého okna, jak máme slíbeno. Využijeme na to přetíženou metodu viewDidAppear(). Nemůžeme použít viewDidLoad(), protože v tomto stádiu ještě není plně inicializované okno (i když k tomu název svádí) a nedostali bychom se k němu.

Pro jistotu nezapomeneme také zavolat super.viewDidAppear().

Základní kostra metody v AddPersonViewController tedy vypadá takto:

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

Co vlastně potřebujeme udělat?

Nejdříve získat pozici prvního okna, získat rámeček druhého okna (kvůli rozměrům), vypočítat korektní pozici a nastavit ji druhému oknu. Celá metoda bude vypadat 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čítá pozice od levého dolního rohu, zatímco iOS (v UIKit) od levého horního.

Pro korektní pozici tedy zjistíme střední Y a X souřadnice a od každé odečteme polovinu šířky respektive výšky, čímž získáme korektní pozici pro druhé okno.

Můžeme vyzkoušet:

Otevření dialogového okna na střed v macOS a Swift

Tímto jsme úspěšně dokončili celé UI, propojili okna mezi sebou a také jsme vyřešili pozicování druhého okna. V následující lekci, Upomínač narozenin pro macOS - Table View a práce s datem, zprovozníme přidávání osob a oživíme Table View.


 

Stáhnout

Staženo 1x (114.77 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
Upomínač narozenin pro macOS - Příprava UI
Všechny články v sekci
Vyvíjíme macOS aplikace ve Swift
Miniatura
Následující článek
Upomínač narozenin pro macOS - Table View a práce s datem
Aktivity (4)

 

 

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í!