Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
Začínáme s
Nastal čas na kakao - Interface Builder: atributy objektů
16. listopadu 2004, 00.00 | V předcházejících dílech jsme připravili datový model naší aplikace, minule jsme v Interface Builderu sestavili její uživatelské rozhraní – nyní už zbývá jen model a rozhraní spojit dohromady pomocí vhodného kontroleru, a aplikace bude hotova.
V předcházejících dílech jsme připravili datový model naší aplikace, minule jsme v Interface Builderu sestavili její uživatelské rozhraní – nyní už zbývá jen model a rozhraní spojit dohromady pomocí vhodného kontroleru, a aplikace bude hotova. Tradičně bývala programování kontrolerů "otrava": to proto, že přitom obvykle nebylo zapotřebí řešit nějaké zajímavé problémy, šlo jen o mechanické implementování spojovacího kódu "když klepneme na tohle tlačítko, stane se s modelem tamto; když se v modelu změní tadyto, zobrazíme to v támhletom textovém poli".
Naštěstí my pracujeme v tom nejlépe navrženém vývojovém systému, jaký se na naší planetě dosud objevil: v Cocoa. Díky tomu máme k dispozici zcela obecné prostředky, jež umožňují implementaci kontrolerů výrazně zjednodušit tím... že je vůbec neimplementujeme. Cocoa totiž obsahuje – převážně díky možnostem dynamického objektového systému jazyka Objective C – standardní třídy a prostředky, jež umožňují požadavky na kontrolery popsat přímo v Interface Builderu. Skutečně: jak uvidíme, naši aplikaci kompletně dokončíme, aniž by bylo zapotřebí napsat jeden jediný řádek zdrojového textu.
Později, až budeme objektovému systému a třídám Cocoa rozumět mnohem lépe než teď, si podrobně vysvětlíme mechanismy, na nichž je tento systém (tzv. bindings) založen, a jak je to vůbec možné, že takto obecně funguje; prozatím však nemáme potřebné znalosti, takže si jen ukážeme, co je třeba udělat v Interface Builderu, a pak se můžeme kochat tím, že to skutečně funguje; konkrétní technické detaily si prozatím vysvětlovat nebudeme.
Kontrolér uživatelských nastavení
Nejjednodušší – alespoň z hlediska konkrétního využití v této naší aplikaci – je standardní kontrolér uživatelských nastavení. Jmenuje se NSUserDefaultsController, a umožňuje nám přímo spojit téměř libovolný prvek grafického uživatelského rozhraní s vhodnou hodnotou v uživatelských předvolbách.
Připomeneme-li si návrh naší aplikace, je to přesně to, co potřebujeme pro textové pole při horním okraji okna: pokud se to, co do něj zapíšeme, uloží do předvoleb s klíčem "LastURL", pak bude korektně fungovat to, co potřebujeme:
- nově vytvořená instance naší modelové třídy RSS se pokusí právě z tohoto URL načíst stream RSS – připomeňme si implementaci její metody init z dílu "Aplikace RSS2: datový model";
- zároveň bude toto URL uloženo v uživatelských předvolbách pro příští spuštění aplikace.
Pro vazbu použijeme opět inspektor Interface Builderu, s nímž jsme se seznámili minule; tentokrát jej však přepneme do režimu "Bindings". Zde můžeme určit vazby pro řadu atributů objektu; my zvolíme "value" (protože právě hodnota textového pole je to, co nás nyní zajímá), a její vazbu určíme tak, jak ukazuje následující obrázek:
Z nabídky "Bind to" vybereme kontroler "Shared User Defaults", a do řádku "Model Key Path" vepíšeme "LastURL". Je také třeba nezapomenout na "Continuously Updates Value", jinak by se nám mohlo stát to, že dokud nestiskneme Enter, hodnota z textového pole se nepoužije, a to by bylo pro uživatele nepohodlné. To je vše! Standardní kontroler se nyní postará o vazbu mezi obsahem textového pole, a položkou v uživatelských předvolbách jež má jméno "LastURL".
Můžeme to hned vyzkoušet – neboť vazby, samozřejmě, jsou také "skutečné objekty", a tedy i v testovacím režimu Interface Builderu fungují stejně dobře, jako budou fungovat potom v samotné aplikaci. Prostě spustíme test již známým příkazem "Test Interface", zapíšeme něco do textového pole, a test ukončíme. Pak test spustíme znovu... a voila, v textovém poli vidíme to, co jsme minule zapsali – právě proto, že se tato hodnota přenesla přes uživatelské předvolby!
Kontrolér pole objektů
Pokračujme dále: máme připraven datový model jako třídu RSS, jež representuje jeden načtený a zpracovaný stream RSS. Jak víme, chceme, aby naše aplikace takovýchto streamů dokázala zpracovat více najednou: potřebujeme tedy zřejmě pole objektů RSS a nějaký kontrolér, který je dokáže spravovat, a který se také postará o to, aby rozevírací nabídka representovala právě objekty z tohoto pole.
Takový kontrolér Cocoa obsahuje: jmenuje se NSArrayController, a je velmi flexibilní a universální. Na rozdíl od objektu NSUserDefaultsController, který nám do aplikace Interface Builder přidal automaticky jakmile jsme nastavili vazbu textového pole, NSArrayController tam musíme přidat sami – to proto, že NSUserDefaultsController je vždy jen jeden, kdežto objektů NSArrayController může být více, různě nastavených – my sami využijeme dva.
Prozatím do projektu umístíme ten první: jako u všech ostatních objektů jej prostě najdeme v paletě – je v té poslední a vypadá jako pár složených krychliček – a vhodíme jej do hlavního okna (jelikož NSArrayController nemá vlastní uživatelské rozhraní, nemělo by smysl jej umísťovat do oken aplikace):
Mimochodem, v okně již vidíme onen zmíněný automaticky přidaný NSUserDefaultsController; jmenuje se "Shared Defaults". Přejmenujeme i NSArrayController na něco rozumného, třeba na "RSS Controller". Označíme jej, a opět použijeme inspektor pro jeho nastavení. Nejprve určíme atributy:
V textovém poli "Object Class Name" kontroléru řekneme, jaká je třída objektů, s nimiž pracuje. Pak již stačí nastavit přepínač "Automatically prepares content", a kontrolér využije této informace k tomu, aby podle potřeby automaticky pole našich objektů vytvořil – ani o to se tedy nemusíme explicitně starat. Ostatní přepínače také zapneme; zajistí, abychom mohli obsah pole měnit ("Editable"), aby kontrolér vždy udržoval některý z jeho prvků zvolený ("Avoids empty selection" – to bude vždy ten prvek, který je v rozevírací nabídce právě vybrán). Jména atributů – v našem případě tedy accesory title, timedTitle a news – bohužel musíme zapsat ručně: Interface Builder do té míry, aby si je dokázal nalézt sám, zdrojové texty analyzovat neumí (alespoň ne v této versi XCode ☺).
Tím jsme zajistili, že náš NSArrayController bude skutečně obsahovat pole instancí třídy RSS – a díky vazbě textového pole na uživatelské předvolby, a díky tomu, že třída RSS při inicializaci právě z předvoleb získá patřičné URL, se také můžeme spolehnout na to, že nově vytvořený objekt v poli bude odpovídat právě URL, jež bylo zapsáno do textového pole. Musíme se ovšem ještě postarat o dvě věci: navázat rozevírací nabídku na kontrolér, aby zobrazovala právě jeho obsah; a také navázat tlačítko "Add" na kontrolér, aby jeho stisknutí přidalo do kontroléru nový objekt. Začneme tlačítkem "Add", je jednodušší: přidržíme přepínač ctrl, a z tlačítka myší táhneme nad objekt "RSS Controller". Interface Builder mezi objekty zobrazí "drát", který representuje jejich vzájemnou vazbu:
V inspektoru – který se automaticky přepne do režimu "Connections" – zvolíme v levé části okna položku target a v pravé zprávu add:. O tomhle jsme se již bavili, vzpomínáte na díl "Podtřídy, delegáti, vkládání..."? Na jeho konci byl odstavec "Mechanismus akce/cíl", a právě tento mechanismus nyní využíváme: při stisknutí tlačítko pošle svému cíli – objektu "RSS Controller" – svou akci – zprávu add:. Můžeme rovnou přesně týmž způsobem připojit tlačítko "Delete" k akci remove:.
Nyní je třeba navázat rozevírací nabídku na obsah kontroléru. To musíme udělat ve dvou krocích: v jednom spolu svážeme obsah rozevírací nabídky s polem, jež je v kontroléru uloženo; ve druhém zvolíme vybraný objekt kontroléru pro zvolený prvek rozevírací nabídky. Označíme tedy rozevírací nabídku, v inspektoru zvolíme režim "Bindings", a nejprve z jeho voleb rozevřeme "contentValues". Jako kontrolér v nabídce "Bind to" pochopitelně vybereme právě "RSS Controller". V nabídce "Controller Key" zvolíme "arrangedObjects"; to je prostě kompletní seznam objektů, jež kontrolér řídí – tedy jinými slovy, všechny naše instance RSS. Konečně, ve třetí položce "Model Key Path" vybereme timedTitle, abychom určili, co má být pro ten který objekt v nabídce zobrazeno – podívejme se na obrázek vlevo:
Pak uzavřeme položku "contentValues" a otevřeme "selectedIndex" – pořadové číslo vybraného objektu – a navážeme jej na selectionIndex kontroléru; "Model Key Path" zde vůbec nepotřebujeme. To vidíme na obrázku vpravo.
(Ostatně, snad se někdo ptá: proč jsou tyto kroky zvlášť? Inu, to je jednoduché: návrháři Cocoa mysleli dopředu, a uvědomili si, že někdy můžeme chtít v nabídkách vybírat jiný aktivní objekt, než ten, který je vybrán v kontroléru. Můžeme třeba mít k jedinému objektu NSArrayController připojeno několik různých rozevíracích nabídek; každá z nich bude vybírat jiný objekt pro jiný účel!)
Nyní už můžeme aplikaci vyzkoušet: pokud jsme při zapisování kódu neudělali žádnou chybu, uložíme-li prostě obsah Interface Builderu a použijeme-li v XCode příkaz "Build & Run", aplikace se vytvoří a bude fungovat – samozřejmě zatím bez tabulky a textového pole v dolní části okna; jen horní textové pole pro vložení URL (můžeme opět použít třeba "http://www.bbc.co.uk/syndication/feeds/news/ukfs_news/world/rss091.xml"), obě tlačítka, a rozevírací nabídka.
Příště už vazbu mezi uživatelským rozhraním a modelem dokončíme, a ukážeme si také několik malých vylepšení a triků pro to, aby byla aplikace k uživateli přívětivější. Zkuste se do té doby zamyslet nad tím, proč jsme pro toto testování museli aplikaci zbuildovat v XCode, a proč jsme si nevystačili jen se starým dobrým "Test Interface" v Interface Builderu!
Obsah seriálu (více o seriálu):
- Nastal čas na kakao...
- Tak nejdřív kakao ochutnáme...
- Programovací jazyk C: velmi, velmi stručně
- Objective C: to si vysvětlíme podrobněji
- Co jsme si o Objective C ještě neřekli...
- Nastal čas na kakao - Vznik a zánik objektů
- Nastal čas na kakao - Kopírování objektů
- Nastal čas na kakao - Skryté podtřídy
- Nastal čas na kakao - Základní služby objektů
- Nastal čas na kakao - Jak správně psát v Objective C
- Nastal čas na kakao - Jak správně importovat
- Nastal čas na kakao - Podtřídy, delegáti, vkládání, jak se to rýmuje?
- Nastal čas na kakao - Využití kategorií namísto dědičnosti
- Nastal čas na kakao - Vkládání objektů a přesměrování zpráv
- Nastal čas na kakao - Inicializace a rušení objektů
- Nastal čas na kakao - Metody initWith... a designovaný inicializátor
- Nastal čas na kakao - Inicializace: tipy a triky
- Nastal čas na kakao - Accesory: přístup k proměnným instancí
- Nastal čas na kakao - Šedá je teorie, zelený je strom života...
- Nastal čas na kakao - Více o XCode: inspektory
- Nastal čas na kakao - Aplikace RSS2: datový model
- Nastal čas na kakao - Aplikace RSS: implementace datového modelu
- Nastal čas na kakao - Aplikace RSS: parsování XML
- Nastal čas na kakao - Interface Builder a uživatelské rozhraní
- Nastal čas na kakao - Interface Builder: atributy objektů
- Nastal čas na kakao - Interface Builder: atributy objektů
- Nastal čas na kakao - Druhý kontrolér a dokončení aplikace
- Nastal čas na kakao - Drobná vylepšení a zdokonalení...
- Nastal čas na kakao - Ladění
- Nastal čas na kakao - Třídy Foundation Kitu
- Nastal čas na kakao - Třídy Foundation Kitu (2)
- Nastal čas na kakao - Textové řetězce: NS(Mutable)String
- Nastal čas na kakao - Čísla, binární data a další...
- Nastal čas na kakao - Archivace objektů
- Nastal čas na kakao - Trocha magie, aneb distribuované objekty
- Nastal čas na kakao - Málem bychom zapomněli: NSAutoreleasePool
- Nastal čas na kakao - Zpracování výjimek: NSException
- Nastal čas na kakao - NSInvocation a černá magie
- Nastal čas na kakao - Kakao v Tygrovi
- Nastal čas na kakao - Notifikace: nepřímé předávání zpráv
- Nastal čas na kakao - NSUserDefaults
- Nastal čas na kakao - Co nového ve Foundation Kitu
- Nastal čas na kakao – s Intelem, s Intelem, jedeme do...
- Co nového v Xcode
- Začínáme s AppKitem
- Jak MVC v Kakau vypadá doopravdy?
- Jak MVC v Kakau vypadá doopravdy: dokončení
- Přehled tříd AppKitu
- Nastal čas na kakao - Přehled tříd AppKitu 2
- Přehled tříd AppKitu 3: zbývající třídy GUI
- Přehled tříd AppKitu 4: textový systém
- Nastal čas na kakao - Přehled tříd AppKitu 5: hlavně grafika
- Přehled tříd AppKitu 6: dokumentový systém
- Přehled tříd AppKitu 7: dokončení
- Pojmenované vlastnosti objektů
- Pojmenované vlastnosti objektů: implementace
- Pojmenované vlastnosti objektů: relace 1:N
- Pojmenované vlastnosti objektů: řazení jmen a agregační funkce
- Sledování změn objektů
- Sledování změn objektů – ukázka
- Sledování změn objektů – zdrojový kód
- Sledování změn objektů: kód modelu
- Sledování změn objektů: přímý přístup
- Kontroléry a vazby
- Vázání vazeb
- Další vazby s jednoduchým kontrolérem
- Implementace a použití převodu hodnot
- Validace hodnot
- Validace a chyby, a jedna hezká vazba...
- Práce s polem objektů
- Základní vazby NSArrayControlleru
- Převodníky, přepínače, placeholdery
- Mírná vylepšení v mezích zákona
- Objective C 2.0 - novinky z Leoparda
- NSTreeController
- Programování v Cocoa - Pár tipů a triků
- Programování v Cocoa - Základy kreslení
- Kterak nakreslit modrý obdélník...
- Další služby pro kreslení
- Obrázky a písmenka...
- Události a myš
- Lepší práce s myší
- Události klávesnice
- Input Management
- Příkazy a schránka
- Další události
- Táhni a padni
- Byli jsme na tahu; nyní padneme.
- Zvolme si, jak vhodit
- Drobnosti a chybičky
- Speciální případy tahání či házení
- Kterak táhnout něco, co neexistuje?
- Jak na sítě...
- NSURLConnection
- Safari za minutu
- Služby WebKitu
- Kakao v Leopardu
- Druhé Objective C
- Druhé Objective C: různé drobnosti
- Druhé Objective C: kategorie a protokoly
- Druhé Objective C: nový příkaz cyklu
- Druhé Objective C: atributy a accesory
- Druhé Objective C: atributy a accesory
- 64 je dvakrát 32
- Ubicumque dulce est, ibi et acidum invenies...
- Irbis: že prý žádné novinky?
- Blok sem, blok tam, nám už je to všechno jasné...
- Bloky jsou i v AppKitu
- Irbis a Foundation Kit
- Kde jsou má data?
- Kde jsou má data? V NSCache!
- Soubor, jméno, URL, jak se to rýmuje...
- Další podpora NSURL
- Zabíjení!
- A máme tady i...OS!
- Systémové prvky GUI
- Programování pro iOS 1. díl - Rozdíly mezi "i" a "Mac"
- Programování pro iOS - 2. Začínáme programovat
- Programování pro iOS - 3. základní ovladače a propojení GUI s kódem
- Programování pro iOS - 4. Varovná hlášení
- Programování pro iOS - 5. Rámce a jejich řídicí objekty
- Programování pro iOS - 6. Ukládání dat
- Programování pro iOS - 7. Správa paměti a starý restík
- Programování pro iOS - 8. Dokončení aplikace
- Programování pro iOS - 9. Jak dostat aplikaci do iPhone
- Programování pro iOS - 10. Instalace aplikace do cizího iPhone
- Programování pro iOS - 11. Jak dostat aplikaci do libovolného iPhone
- Programování pro iOS - 12. Touching!
- Programování pro iOS - 13. Kreslíme na iPhone
- Programování pro iOS - 14. Udělejme gesto
- Programování pro iOS - 15. Další gesta
- Programování pro iOS - 16. Více prstů, více zábavy
- Programování pro iOS - 17. Podpora standardních gest
- Programování pro iOS - 18. Recognizery v iOS
- Programování pro iOS - 19. Další standardní recognizery
- Programování pro iOS - 20. Co nového v iOSu
- Programování pro iOS - 21. "Multitasking"
- Programování pro iOS - 22. Nulla est honesta avaritia nisi temporis
- Programování pro iOS - 23. Jak se aktivovat, jsme-li v pozadí
- Programování pro iOS - 24. Zbývající drobnosti
- Programování pro iOS - 25. Řídicí objekty rámců
- Programování pro iOS - 26. Jak se dělá UIViewController
- Programování pro iOS - 27. Kde vzít rámce
- Programování pro iOS - 28. Základní služby
- Programování pro iOS - 29. Práce s rámci
- Programování pro iOS - 30. Rotace zařízení
- Programování pro iOS - 31. Správa paměti v rámcích
- Programování pro iOS - 32. Řídicí objekt pro tabulky
- Programování pro iOS - 33. Řídicí objekt pro strom
- Programování pro iOS - 33. Více o UINavigationControlleru
- Programování pro iOS - 35. Ještě jednou UINavigationController
- Programování pro iOS - 36. Po navigátoru taby
- Programování pro iOS - 37. Více o UITabBarControlleru
- Programování pro iOS - 38. Dokončení UITabBarControlleru
- Programování pro iOS - 39. UIPopoverController
- Programování pro iOS - 40. Další triky UIPopoverControlleru
- Programování pro iOS - 41. Zbývající služby UIPopoverControlleru
- Programování pro iOS - 42. UISplitViewController
- Programujeme v
iTunesXcode 4 - Programování pro iOS - 44. Předvolby Xcode 4
- Programování pro iOS - 45. Práce v Xcode 4
- Xcode 4: projekt a cíle
- Xcode 4: práce s cíli
- Xcode 4: Build Settings
- Xcode 4: Build Phases
- Xcode4: Build Phases podruhé
- Xcode 4: Co jsou to Build Rules?
- Xcode4: taje editoru
- Xcode4: automatické doplňování v editoru
- XIBy chyby
- Více o XIBech
- Editor XIBů
- Inspektory pro XIBy
- Vazby mezi objekty v XIBech
- Vazby mezi objekty v kódu
- Paletky Xcode pro XIBy
- Xcode 4: levý sloupec
- Xcode 4: okno Organizer
- Xcode 4: okno Organizer, část druhá
- Xcode 4: co je to Workspace?
- Xcode 4: základy schémat
- Xcode 4: akční schémata