私の知る限りでは、非標準のスタイル変更を行うために、UINavigationBarをサブクラス化する必要がある場合があります。カテゴリを使用することで回避する必要がない場合もありますが、常にそうであるとは限りません。
現在、私が知る限り、唯一の UIViewController内でカスタムUINavigationBarを設定する方法は、IBを介して(つまり、アーカイブを介して)です-おそらくそのようにすべきではありませんが、今のところ、それを使用します。
これは多くの場合問題ありませんが、IBを使用することは実際には現実的ではありません。
だから、私は3つのオプションを見ました:
- UINavigationBarをサブクラス化し、それをすべてIBに接続します。次に、UINavigationControllerが必要になるたびにnibをロードします。
- メソッド置換を使用サブクラス化ではなく、カテゴリ内で UINavigationBarの動作を変更する、または
- UINavigationBarをサブクラス化し、UINavigationControllerのアーカイブ/アーカイブ解除を少し変更します。
私はUINavigationControllerをプログラムで作成する必要があったので、この場合、オプション1は実現不可能でした(または、少なくとも煩わしくなりました)。2は少し危険で、私の意見では最後の手段であるので、オプション3を選択しました。
私のアプローチは、UINavigationControllerの「テンプレート」アーカイブを作成し、それをアーカイブ解除してに返すことinitWithRootViewController
でした。
方法は次のとおりです。
IBでは、UINavigationBarに適切なクラスセットを使用してUINavigationControllerを作成しました。
次に、既存のコントローラーを取得し、を使用してそのアーカイブコピーを保存しました+[NSKeyedArchiver archiveRootObject:toFile:]
。これは、アプリデリゲート内のシミュレータで行いました。
次に、-iフラグを指定して 'xxd'ユーティリティを使用し、保存したファイルからCコードを生成して、アーカイブバージョンをサブクラスに埋め込みました(xxd -i path/to/file
)。
中でinitWithRootViewController
私は未アーカイブの結果にそのテンプレート、および設定した自己のアーカイブ解凍します:
// 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];
}
次に、カスタムナビゲーションバーが設定されているUIViewControllerサブクラスの新しいインスタンスを取得します。
UIViewController *modalViewController = [[[CTNavigationController alloc] initWithRootViewController:myTableViewController] autorelease];
[self.navigationController presentModalViewController:modalViewController animated:YES];
これにより、ナビゲーションバーとツールバーがすべて設定され、カスタムナビゲーションバークラスが配置されたモーダルUITableViewControllerが得られます。少し厄介なメソッドの置換を行う必要はありませんでした。プログラムで作業したいだけの場合は、ペン先をいじくる必要はありません。
+layerClass
UINavigationController内で同等のものを見たいのです+navigationBarClass
が、今のところ、これでうまくいきます。