我的项目中有许多 UIViewControllers 实现了 UITableViewDataSource 和 UITableViewDelegate 协议。在 Interface Builder 中,我删除了 UIView 并将其替换为子类 UITableView。在我的子类 UITableView 中,我设置了一个自定义背景视图。
@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
这一切都很好。我有六个左右的 UIViewControllers,它们都有 UITableViews 的子类,它们都绘制了我的背景图像。我的背景图像很暗,所以我需要绘制我的部分标题,以便它们可见。谷歌搜索我发现如何更改分组类型 UITableView 中标题的字体颜色?我在我的子类中实现了 viewForHeaderInSection。
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
...
我的 viewForHeaderInSection 没有被调用。当然,当我想了一会儿,这是有道理的。我的 UIViewControllers 是实现 UITableViewDataSource 和 UITableViewDelegate 的对象,当我将 viewForHeaderInSection 放入我的 UIViewControllers 之一时,它工作得很好。
但是,我有六个这样的 UIViewController,它们都属于不同的类,实现了不同的功能。所以我决定在我的子类 UIViewControllers 和 UIViewController 之间放置一个类。这样,设置节标题外观的通用代码将在一个位置,而不是在六个位置。
所以我写:
@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 中,我实现了一些 Table Protocol 方法,但没有实现 viewForHeaderInSection。我还在 FFViewController 上收到警告,因为它没有实现所有协议(这是故意的,本示例中的子类 FooDetailsViewController 填写了协议。)
那么问题是什么?
并非所有其他子类 UIViewController 都响应 titleForHeaderInSection,所以当我运行时,我当然会在这些视图控制器上崩溃。所以我尝试看看是否实现了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,因为它没有节标题
(感谢您阅读本文!)