Sejauh yang saya tahu, terkadang memang perlu untuk membuat subclass UINavigationBar, untuk melakukan beberapa pengaturan ulang gaya yang tidak standar. Terkadang mungkin untuk menghindari keharusan melakukannya dengan menggunakan kategori , tetapi tidak selalu.
Saat ini, sejauh yang saya tahu, satu - satunya cara untuk menyetel UINavigationBar khusus dalam UIViewController adalah melalui IB (yaitu, melalui arsip) - mungkin seharusnya tidak seperti itu, tetapi untuk saat ini, kita harus menerimanya.
Ini sering kali baik-baik saja, tetapi terkadang menggunakan IB tidak terlalu memungkinkan.
Jadi, saya melihat tiga opsi:
- Subclass UINavigationBar dan kaitkan semuanya di IB, lalu buang waktu setiap kali saya menginginkan UINavigationController,
- Gunakan penggantian metode dalam kategori untuk mengubah perilaku UINavigationBar, bukan subclassing, atau
- Subclass UINavigationBar dan lakukan sedikit penyia-nyiaan dengan pengarsipan / pengarsipan UINavigationController.
Opsi 1 tidak layak (atau setidaknya terlalu menjengkelkan) bagi saya dalam hal ini, karena saya perlu membuat UINavigationController secara terprogram, 2 sedikit berbahaya dan lebih merupakan opsi terakhir menurut saya, jadi saya memilih opsi 3.
Pendekatan saya adalah membuat arsip 'template' dari UINavigationController, dan membatalkan pengarsipannya, mengembalikannya ke dalam initWithRootViewController
.
Begini caranya:
Dalam IB, saya membuat UINavigationController dengan kelas yang sesuai untuk UINavigationBar.
Kemudian, saya mengambil pengontrol yang ada, dan menyimpan salinan yang diarsipkan menggunakan +[NSKeyedArchiver archiveRootObject:toFile:]
. Saya baru saja melakukan ini di dalam delegasi aplikasi, di simulator.
Saya kemudian menggunakan utilitas 'xxd' dengan flag -i, untuk menghasilkan kode c dari file yang disimpan, untuk menyematkan versi yang diarsipkan di subclass saya ( xxd -i path/to/file
).
Di dalam initWithRootViewController
saya membatalkan pengarsipan template itu, dan mengatur diri ke hasil dari pengarsipan:
// This is the data from [NSKeyedArchiver archivedDataWithRootObject:controller], where
// controller is a CTNavigationController with navigation bar class set to CTNavigationBar,
// from IB. This c code was created using 'xxd -i'
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 {
// Replace with unarchived view controller, necessary for the custom navigation bar
[self release];
self = (CTNavigationController*)[NSKeyedUnarchiver unarchiveObjectWithData:[NSData dataWithBytes:archived_controller length:archived_controller_len]];
[self setViewControllers:[NSArray arrayWithObject:rootViewController]];
return [self retain];
}
Kemudian, saya bisa mengambil contoh baru dari subkelas UIViewController saya yang memiliki bilah navigasi khusus:
UIViewController *modalViewController = [[[CTNavigationController alloc] initWithRootViewController:myTableViewController] autorelease];
[self.navigationController presentModalViewController:modalViewController animated:YES];
Ini memberi saya modal UITableViewController dengan bilah navigasi dan bilah alat yang sudah disiapkan, dan dengan kelas bilah navigasi khusus di tempatnya. Saya tidak perlu melakukan penggantian metode yang sedikit menjengkelkan, dan saya tidak perlu mengotak-atik nib ketika saya benar-benar hanya ingin bekerja secara terprogram.
Saya ingin melihat padanan +layerClass
dalam UINavigationController - +navigationBarClass
- tetapi untuk saat ini, ini berfungsi.