プロジェクトには、UITableViewDataSourceプロトコルとUITableViewDelegateプロトコルを実装するUIViewControllerがいくつかあります。Interface Builderで、UIViewを削除し、サブクラス化されたUITableViewに置き換えました。サブクラス化されたUITableViewで、カスタムbackgroundViewを設定しました。
@interface FFTableView : UITableView
@end
@implementation FFTableView
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder]; // Required. setFrame will be called during this method.
self.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background.png"]];;
return self;
}
@end
これはすべて正常に機能します。私はこれらのUIViewControllerを半ダースほど持っており、それらはすべてUITableViewsをサブクラス化しており、それらはすべて私の背景画像を描画します。背景画像が暗いので、セクションヘッダーが見えるように描画する必要があります。グーグル私はグループ化されたタイプUITableViewでタイトルのフォントの色を変更する方法を見つけましたか?そして、サブクラスにviewForHeaderInSectionを実装します。
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
...
私のviewForHeaderInSectionは呼び出されません。もちろん、ちょっと考えてみると理にかなっています。私のUIViewControllersは、UITableViewDataSourceとUITableViewDelegateを実装するオブジェクトであり、UIViewControllersの1つにviewForHeaderInSectionを配置すると、正常に機能します。
しかし、私はこれらのUIViewControllerを半ダース持っており、すべてが異なるクラスにサブクラス化されており、異なる機能を実装しています。そこで、サブクラス化されたUIViewControllersとUIViewControllerの間にクラスを配置することにしました。このように、セクションヘッダーの外観を設定する一般的なコードは、半ダースのスポットではなく、1つのスポットになります。
だから私は書く:
@interface FFViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
@end
ここで、viewForHeaderInSectionを実装します。
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSString *sectionTitle = [self tableView:tableView titleForHeaderInSection:section];
if (sectionTitle == nil) {
return nil;
}
...
他のサブクラス化されたコントローラーをFFViewControllerの子孫に変更します。これが次のとおりです。
@interface FooDetailsViewController : FFViewController
2か所に外観コードがあるのは少し奇妙に思えますが、同じコードのコピーがいたるところに散らばっているよりはましです。FooDetailsViewControllerで、いくつかのテーブルプロトコルメソッドを実装しますが、viewForHeaderInSectionは実装しません。FFViewControllerはすべてのプロトコルを実装していないため、警告も表示されます(これは意図的に、子クラス、この例ではFooDetailsViewControllerがプロトコルに入力します)。
それで、質問は何ですか?
他のサブクラス化されたUIViewControllerのすべてがtitleForHeaderInSectionに応答するわけではないので、もちろん、実行すると、それらのViewControllerでクラッシュします。だから私はtitleForHeaderInSectionが実装されているかどうかを確認しようとします:
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
if (![self respondsToSelector:@selector(titleForHeaderInSection)]) {
return nil;
}
NSString *sectionTitle = [self tableView:tableView titleForHeaderInSection:section];
if (sectionTitle == nil) {
return nil;
}
また、respondsToSelectorは常にfalseを返します。したがって、そのセクションを強制終了して、すべてのサブクラスにtitleForHeaderInSectionを実装するように強制できますが、それは間違っているようです。
この状況から抜け出すための良い方法は何ですか?私はすでに解決策を嫌っています:
- コードには警告があります。(しかし、部分的な基本クラスで「不完全な実装」の警告を回避してそれらを停止する方法はいつでも実行できます)
- 私の外観コードは2つの別々のクラスにあります
- セクションヘッダーがないため、titleForHeaderInSectionを必要としないコードに実装する必要があります
(ここまで読んでくれてありがとう!)