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:
Software
Programování pro iOS - 32. Řídicí objekt pro tabulky
9. března 2011, 06.00 | V současnosti se náš seriál soustředí na řídicí objekty rámců. V minulých dílech jsme se seznámili s obecnými službami, jež nám nabízí sama třída UIViewController (a tedy také všechny její podtřídy); dnes se začneme věnovat některým speciálním řídicím objektům, jež iOS nabízí.
Docela určitě nejjednodušším ze všech specializovaných řídicích objektů rámců je UITableViewController – řídicí objekt, specializovaný na ovládání tabulky. Proto jím dnes začneme, a na složitější řídicí objekty – jako je třeba UITabViewController – se podíváme v příštích dílech.
Co vlastně umí?
Služeb, které nabízí UITableViewController navíc oproti své nadřízené třídě UIViewController, není mnoho, a už řadu programátorů určitě napadlo, že je otázka, stálo-li firmě Apple vůbec za to jej vytvářet v API jako samostatnou třídu. Jedná se pouze o následující funkce:
• pokud necháme řídicí objekt, aby sám vytvořil standardní rámec (tedy nepoužijeme-li ani XIB, ani některou z možností pro jeho programové sestavení), bude to rámec třídy UITableView, nikoli UIView;
• pro pohodlný přístup bez přetypování také třída nabízí atribut tableView; ten vždy obsahuje kořenový rámec (stejně jako zděděný atribut view), ale navíc má správný typ. Neobjektová ošklivost, ale vzhledem k nešťastně navrženým atributům šikovná...
• nevyžádáme-li si jinak, řídicí objekt automaticky sám sebe uloží do atributů dataSource a delegate svého rámce – aniž bychom se o to tedy museli explicitně starat, bude mu dodávat data a bude řídit jejich vzhled;
• řídicí objekt po inicializaci pošle rámci zprávu reloadData;
• řídicí objekt před zobrazením tabulky může – chceme-li – zrušit seznam vybraných řádků (v závislosti na nastavení atributu clearsSelectionOnViewWillAppear);
• po zobrazení tabulky na chvilku zobrazí scollery, aby uživatel měl představu o tom, jaká část tabulky je zobrazena;
• podporuje přepínání tabulky do editačního režimu pomocí odpovídajícího tlačítka (standardně – ale ne nutně – "Edit" v pravém horním rohu).
Vidíme, že jde o poměrně jednoduchou skupinu služeb, jež by bylo poměrně pohodlné implementovat "ručně"; přesto ale to, že je máme k dispozici hotové, dokáže nějaký ten čas ušetřit.
Co neumí?
Asi hlavní nevýhodou třídy UITableViewController je to, že její atribut tableView povinně musí odkazovat na týž objekt jako zděděný atribut view – a tento objekt musí být řízená tabulka. Není tedy speciálně možné s využitím služeb této třídy implementovat správu obrazovky, v níž tabulka (rámec UITableView) není jediným a kořenovým objektem, ale pouze jedním z více prvků složitějšího GUI.
Potřebujeme-li sestavit takovou strukturu rámců, nezbývá, než použít "obyčejný" UIViewController, a všechny výše zmíněné služby (resp. ty z nich, jež skutečně potřebujeme, ale obvykle to bývá většina z výše zmíněných) si implementovat sami.
V ostatních případech bývá pohodlnější vytvořit řídicí objekt jako dědice UITableViewController a implementovat jen to, co je "navíc".
Služby
Programátorské rozhraní, které třída UITableViewController nabízí, je velice jednoduché, a téměř celé jsme si je již popsali: oproti třídě UIViewController zde jsou totiž pouze tři novinky, a dvě z nich již známe – atribut
@property(nonatomic, retain) UITableView *tableView;
pro "správně otypovaný" přístup ke kořenovému rámci, stejně jako atribut
@property(nonatomic) BOOL clearsSelectionOnViewWillAppear;
jehož hodnota (standardně YES) rozhoduje, zda řídicí objekt vždy před zobrazením tabulky zruší seznam vybraných řádků, jsme si popsali výše.
Třetí změnou je nový inicializátor
-(id)initWithStyle:(UITableViewStyle)style;
Tabulky v iOS jsou velmi flexibilní a podporují hodně bohatou paletu různých vzhledů, od zcela klasické tabulky až po to, co používá většina aplikací pro nastavování parametrů – spustíte-li aplikaci "Settings", uvidíte tabulku. Těm klasickým odpovídá tzv. obyčejný styl UITableViewStylePlain (a to je také standardní hodnota, pokud použijeme některý ze zděděných inicializátorů); tomu, co známe např. z aplikace "Settings", odpovídá styl "skupinový" – UITableViewStyleGrouped.
Pokud necháme UITableViewController tabulku automaticky vytvářet – a jak si ukážeme níže, je to poměrně běžné –, můžeme si právě tímto argumentem vyžádat její vzhled. Pokud samozřejmě tabulku načteme z XIBu nebo vytvoříme programově, bude mít ten vzhled, jaký je v XIBu nebo jaký si vyžádáme při jejím vytváření.
Jednoduchá ukázka
Samozřejmě, že do řídicího objektu tabulky můžeme přidat řadu služeb; bezpodmínečně ale musíme doplnit přinejmenším metody pro řízení tabulky – služby jejího datového zdroje a delegáta. Ponecháme-li tedy stranou nepravděpodobnou (ale ovšem možnou) situaci, v níž by tabulka měla odlišný datový zdroj, nikdy nepoužijeme přímo třídu UITableViewController, ale vždy nějakou její vlastní podtřídu.
Naproti tomu je velmi častý případ to, že pro tabulku nepoužijeme žádný XIB, a vše, co je zapotřebí, nastavíme čistě programově.
Jako ukázku si implementujeme velmi jednoduchou třídu, která nám umožní zobrazovat tabulky předem daných textů a vybírat z nich:
@interface SelectionVC:UITableViewController
+(SelectionVC*)selectionWithList:(NSArray*)items;
@end
extern NSString * const SelectionVCNotification;
Naše API je naprosto triviální: nabízí jen jedinou službu, selectionWithList:; zde pole "items" obsahuje texty, z nichž můžeme vybírat. Jakmile hotový řídicí objekt rámce umístíme na obrazovku – nejspíše asi pomocí služby presentModalController:animated: – řídicí objekt zobrazí tyto texty v tabulce a nechá uživatele zvolit některý z nich. Zvolený index pak bude rozeslán pomocí notifikace SelectionVCNotification.
Ani implementace, jak uvidíme, nebude příliš složitá – začneme definicí potřebných atributů, a protože není třeba, aby byly veřejné, použijeme k tomu tzv. rozšíření, jež bude spolu s vlastní implementací v témže zdrojovém souboru:
@interface SelectionVC
@property (retain,nonatomic) NSArray *items;
@end
@implementation SelectionVC
@synthesize items, selectedIndex;
...
V dalším kroku pak implementujeme standardní inicializační metodu, odpovídající nutnou metodu dealloc, a také jedinou veřejnou službu selectionWithList:...
-initWithItems:(NSArray*)ia {
if (!(self=[super init])) return nil;
self.items=ia;
return self;
}
-(void)dealloc {
self.items=nil;
[super dealloc];
}
+(SelectionVC*)selectionWithList:(NSArray*)items {
return [[[self alloc] initWithItems:items] autorelease];
}
...
Zbývá už jen implementovat služby datového zdroje a delegáta tabulky. My jsme se s nimi již setkali na začátku v ukázce "bouřlivé" aplikace, takže pro nás nebudou žádnou zásadní novinkou – z celé bohaté palety možných metod stačí implementovat tři, dvě pro zobrazení obsahu tabulky a třetí pro výběr jejího řádku:
...
-(NSInteger)tableView:(UITableView*)tv
numberOfRowsInSection:(NSInteger)section {
return self.items.count;
}
-(UITableViewCell*)tableView:(UITableView*)tv
cellForRowAtIndexPath:(NSIndexPath*)ip {
UITableViewCell *cell=nil;
if (!(cell=[tv dequeueReusableCellWithIdentifier:@"0"]))
cell=[[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"0"]
autorelease];
cell.textLabel.text=[self.items objectAtIndex:ip.row];
return cell;
}
-(NSIndexPath*)tableView:(UITableView*)tv
willSelectRowAtIndexPath:(NSIndexPath*)ip {
[[NSNotificationCenter defaultCenter]
postNotification:SelectionVCNotification object:self
userInfo:[NSDictionary
dictionaryWithObject:[NSNumber numberWithInteger:ip.row]
forKey:@"row"]];
return nil;
}
@end
A to je celé.
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