iOS8 中,UITableViewCell无法显示detailTextLabel由以下三种情况:(由于无iOS8系统的手机,故无法验证前两种,如有朋友能验证的,希望在下面留言,谢谢。第三种为亲身遭遇。)
<1> IOS8 UITableViewCell.detailTextLabel不显示解决方法中的解释为iOS8存在系统bug,需要这样处理:
用到了一个检测系统版本的宏:
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
tableView: cellForRowAtIndexPath处理如下:
#define CELL_REUSE_IDENTIFIER @"UITableViewCell"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CELL_REUSE_IDENTIFIER];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CELL_REUSE_IDENTIFIER];
}
cell.textLabel.text = @"textLabel";
cell.detailTextLabel.text = @"detailTextLabel";
// to support ios8.0
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
[cell layoutSubviews];
}
return cell;
}
<2> 总结iOS 8和Xcod 6的各种坑中的解释为: 测试发现,当detailTextLabel的text一开始为空,iOS 8下运行就会把这个label的size设置(0, 0)从而不能正确显示
也就是说,代码需要检查,当cell.detailTextLabel.text初始值为@""时,需要人为来添加一个空格@" "。
tableView: cellForRowAtIndexPath处理如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CELL_REUSE_IDENTIFIER];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CELL_REUSE_IDENTIFIER];
}
cell.textLabel.text = @"textLabel";
NSString *detailTextLabelStr = @"";
cell.detailTextLabel.text = detailTextLabelStr;
// to support ios8.0
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
if ([cell.detailTextLabel.text length]==0) {
cell.detailTextLabel.text = @" ";
}
[cell layoutSubviews];
}
return cell;
}
在使用其他开源代码中,由于未注意这个错误,导致我找了一整个下午,才发现原因:
在UITableView.h中:
- (nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier;
- (void)registerClass:(nullable Class)cellClass forCellReuseIdentifier:(NSString *)identifierNS_AVAILABLE_IOS(6_0);
这两个API是冲突的。参考代码如下:
#define CELL_REUSE_IDENTIFIER @"MainUIViewControllerCell"
- (void)viewDidLoad
{
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:CELL_REUSE_IDENTIFIER];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CELL_REUSE_IDENTIFIER];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CELL_REUSE_IDENTIFIER];
}
ESPDevice *device = [self.deviceArray objectAtIndex:indexPath.row];
cell.textLabel.text = [self tableViewCellTextLabelText:device];
cell.detailTextLabel.text = [self tableViewCellDetailTextLabelText:device];
// to support ios8.0
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
[cell layoutSubviews];
}
return cell;
}
由于viewDidLoad()中调用了registerClass: forCellReuseIdentifier: 。
所以,tableView: cellForRowAtIndexPath中的[tableView dequeueReusableCellWithIdentifier:]返回的都不是nil。并且,cell的style一直是UITableViewCellStyleDefault,所以detailTextLabel无法显示。