O ile wiem, czasami rzeczywiście konieczne jest utworzenie podklasy UINavigationBar w celu wykonania niestandardowej zmiany stylizacji. Czasami można tego uniknąć, używając kategorii , ale nie zawsze.
Obecnie, o ile wiem, jedynym sposobem ustawienia niestandardowego UINavigationBar w kontrolerze UIViewController jest IB (czyli archiwum) - prawdopodobnie nie powinno tak być, ale na razie musimy z tym żyć.
Często jest to w porządku, ale czasami użycie IB nie jest naprawdę wykonalne.
Widziałem więc trzy opcje:
- Podklasa UINavigationBar i podłącz to wszystko do IB, a następnie zajmij się ładowaniem stalówki za każdym razem, gdy chcę UINavigationController,
- Użyj zamiany metody w kategorii, aby zmienić zachowanie UINavigationBar zamiast podklasy lub
- Podklasa UINavigationBar i trochę pomieszaj przy archiwizowaniu / cofaniu archiwizacji UINavigationController.
Opcja 1 była dla mnie niewykonalna (lub przynajmniej zbyt irytująca) w tym przypadku, ponieważ musiałem programowo utworzyć UINavigationController, 2 jest trochę niebezpieczna i moim zdaniem jest bardziej ostateczną opcją, więc wybrałem opcję 3.
Moje podejście polegało na utworzeniu archiwum „szablonu” kontrolera UINavigationController i przywróceniu go z archiwum, zwracając go w formacie initWithRootViewController
.
Oto jak:
W IB stworzyłem UINavigationController z odpowiednim zestawem klas dla UINavigationBar.
Następnie wziąłem istniejący kontroler i zapisałem jego zarchiwizowaną kopię za pomocą +[NSKeyedArchiver archiveRootObject:toFile:]
. Właśnie to zrobiłem w ramach delegata aplikacji, w symulatorze.
Następnie użyłem narzędzia „xxd” z flagą -i, aby wygenerować kod c z zapisanego pliku, aby osadzić zarchiwizowaną wersję w mojej podklasie ( xxd -i path/to/file
).
Wewnątrz initWithRootViewController
rozpakowuję ten szablon i ustawiam się na wynik przywrócenia z archiwum:
static unsigned char archived_controller[] = {
0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd4, 0x01, 0x02, 0x03,
...
};
static unsigned int archived_controller_len = 682;
...
- (id)initWithRootViewController:(UIViewController *)rootViewController {
[self release];
self = (CTNavigationController*)[NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithBytes:archived_controller length:archived_controller_len]];
[self setViewControllers:[NSArray arrayWithObject:rootViewController]];
return [self retain];
}
Następnie mogę po prostu pobrać nowe wystąpienie mojej podklasy UIViewController, która ma ustawiony niestandardowy pasek nawigacji:
UIViewController *modalViewController = [[[CTNavigationController alloc] initWithRootViewController:myTableViewController] autorelease];
[self.navigationController presentModalViewController:modalViewController animated:YES];
Daje mi to modalny UITableViewController ze skonfigurowanym paskiem nawigacji i paskiem narzędzi oraz z niestandardową klasą paska nawigacji. Nie musiałem wykonywać żadnej nieco nieprzyjemnej zamiany metody i nie muszę majstrować przy końcówkach, gdy naprawdę chcę pracować programowo.
Chciałbym zobaczyć odpowiednik +layerClass
w UINavigationController - +navigationBarClass
- ale na razie to działa.