问题是:我有一个自定义表格视图单元格,由表格视图使用,而表格视图又是通用的。该表视图的宽度通过IB设置为240。假设单元格的宽度与表格的宽度相同,我继续添加一些逻辑来计算图像视图和两个标签的范围,然后将这两个标签添加到单元格的内容视图中。事实证明,我的假设是错误的。 试图发现什么是错的,我继续并重写了tableView:willDisplayCell:forRowAtIndexPath:。问题是这个方法显示单元格的宽度将是所需的240个点,但它会在自定义单元格initWithStyle:reuseIdentifier:的指定初始化之后被调用,奇怪的是,它返回320个点。
以下是细胞的初始化:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
NSLog(@"cell frame at init: %@", NSStringFromCGRect(self.contentView.frame));
self.avatarView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.contentView.frame.size.height, self.contentView.frame.size.height)];
[self.contentView addSubview:self.avatarView];
self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.avatarView.frame.size.width + 10, 0, self.frame.size.width - self.avatarView.frame.size.width - 40, self.frame.size.height)];
self.nameLabel.backgroundColor = [UIColor greenColor];
[self.contentView addSubview:self.nameLabel];
self.visitorsLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.avatarView.frame.size.width + self.nameLabel.frame.size.width + 20, 0, self.frame.size.width - (self.avatarView.frame.size.width + self.nameLabel.frame.size.width + 20), self.contentView.frame.size.height)];
self.visitorsLabel.textColor = [UIColor whiteColor];
self.visitorsLabel.backgroundColor = [UIColor redColor];
[self.contentView addSubview:self.visitorsLabel];
}
return self;
}
子视图的信息以不同的方式提供。 这是控制器中的代码,表视图的委托:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NewClubTableCell *cell = [tableView dequeueReusableCellWithIdentifier:@"newCell"];
Club *club = [self.clubs getClubAtIndex:indexPath.row];
cell = [[NewClubTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"newCell"];
[cell setAvatar:club.avatar name:club.name visitors:club.visitors];
return cell;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"table view will display frame: %@", NSStringFromCGRect(cell.frame));
}
这是日志的结果:
2014-05-03 16:18:04.143 FanStation[2436:70b] cell frame at init: {{0, 0}, {320, 44}}
2014-05-03 16:18:04.144 FanStation[2436:70b] table view will display frame: {{0, 0}, {240, 44}}
2014-05-03 16:18:04.145 FanStation[2436:70b] cell frame at init: {{0, 0}, {320, 44}}
2014-05-03 16:18:04.146 FanStation[2436:70b] table view will display frame: {{0, 44}, {240, 44}}
2014-05-03 16:18:04.146 FanStation[2436:70b] cell frame at init: {{0, 0}, {320, 44}}
2014-05-03 16:18:04.147 FanStation[2436:70b] table view will display frame: {{0, 88}, {240, 44}}
2014-05-03 16:18:04.147 FanStation[2436:70b] cell frame at init: {{0, 0}, {320, 44}}
2014-05-03 16:18:04.148 FanStation[2436:70b] table view will display frame: {{0, 132}, {240, 44}}
2014-05-03 16:18:04.148 FanStation[2436:70b] cell frame at init: {{0, 0}, {320, 44}}
2014-05-03 16:18:04.149 FanStation[2436:70b] table view will display frame: {{0, 176}, {240, 44}}
正如您所看到的,表格视图提供了正确的宽度,但是单元格仍然有自己的想法。
我的问题是,如果我在这里做错了,是否有办法纠正这个问题? 如果您需要有关此案例的任何其他信息,我将非常乐意提供此信息。
答案 0 :(得分:12)
表格视图单元格不知道它的初始值设定项应该是多少。它以默认大小(320点)初始化,然后在显示之前调整大小。不要注意init方法中设置的大小。
你所看到的是完全正常的。
您将在视图控制器中看到与主视图相同的内容。视图在viewDidLoad中以其默认大小和方向创建,然后调整大小并旋转以供显示。
如果需要在调整单元格大小时收到通知,则可以实现视图控制器方法didLayoutSubViews。当单元格在初始化后初始化为表视图的大小时,以及在视图控制器的内容视图的大小发生变化之后(例如,在设备旋转之后),将调用它。
答案 1 :(得分:4)
在与@Duncan C和@Basheer_CAD进行非常有益的讨论后,我觉得有必要详细说明我在当前帖子中提出的问题的解决方案。
如果我在单元格外部进行任何UITableViewCell子视图初始化,我认为这将是犯规。因此,按照上面提到的两个建议,我继续覆盖了单元格layoutSubviews
,在那里我创建了子视图的rects。事实证明,layoutSubviews
很晚才到达现场,渲染我的方法为子视图提供的信息毫无用处。所以我不得不创建其他属性来临时存储图像和两个字符串。然后在初始化子视图的过程中使用它们。
同样,这是控制器中的代码,如果你按照数字,你将得到序列:
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NewClubTableCell *cell = [tableView dequeueReusableCellWithIdentifier:@"newCell"];
Club *club = [self.clubs getClubAtIndex:indexPath.row];
(1)
cell = [[NewClubTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"newCell"];
(3)
[cell setAvatar:club.avatar name:club.name visitors:club.visitors];
return cell;
}
这是单元格的初始化程序。如你所见,它什么都不做:
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier avatar:(UIImage *)avatar name:(NSString *)name visitors:(NSInteger)visitors
{
(2)
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
}
return self;
}
数据传输方法:
-(void)setAvatar:(UIImage *)avatar name:(NSString *)name visitors:(NSInteger)visitors
{
(4)
self.avatarImage = avatar;
self.name = name;
self.visitors = [NSString stringWithFormat:@"%d", visitors];
}
最后,layoutSubviews
:
-(void)layoutSubviews
{
(5)
self.avatarView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.contentView.frame.size.height, self.contentView.frame.size.height)];
self.avatarView.image = self.avatarImage;
[self.contentView addSubview:self.avatarView];
self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.avatarView.frame.size.width, 0, self.frame.size.width - self.avatarView.frame.size.width - 40, self.frame.size.height)];
self.nameLabel.text = self.name;
self.nameLabel.backgroundColor = [UIColor greenColor];
[self.contentView addSubview:self.nameLabel];
self.visitorsLabel = [[UILabel alloc] initWithFrame:CGRectMake(self.avatarView.frame.size.width + self.nameLabel.frame.size.width, 0, self.frame.size.width - (self.avatarView.frame.size.width + self.nameLabel.frame.size.width), self.contentView.frame.size.height)];
self.visitorsLabel.text = self.visitors;
self.visitorsLabel.textColor = [UIColor whiteColor];
self.visitorsLabel.backgroundColor = [UIColor redColor];
[self.contentView addSubview:self.visitorsLabel];
}
它的美妙之处在于,无论设备及其方向如何,生命周期中只有一种方法是使整个事物正常运行并正确显示的关键。