前言:这是一个非常抽象的问题。
我在UITableView
中有一些单元格使用不同的图像,具体取决于单元格的高度(以50px为增量,从50px到高达1000px)。我遇到一个奇怪的问题,当应用程序首次加载时,cellForRowAtIndexPath
报告前三个单元格(无论是否所有三个单元格都是onscree)的高度为100px,然后当我向下滚动并备份时再次,他们的高度恢复到正确的值。屏幕上没有高度变化,只有使用的图像发生了变化,cell.frame.size.height
语句中NSLog
的值也没有变化。
我一直在登录heightForRowAtIndexPath
和cellForRowAtIndexPath
,我可以在离开heightForRowAtIndexPath
时验证高度是否正确。但是,当输入cellForRowAtIndexPath
时,前三个高度都统一设置为100.然后向下滚动直到这三个单元格在屏幕外,然后向上滚动,.height
值已更改为正确的价值。
总结一下,我的问题是:
在heightForRowAtIndexPath
的最后和cellForRowAtIndexPath
的最开头之间是否有任何可能正在更改前几个单元格的cell.frame.size.height
值的代码?
为什么这个问题只发生在前三个细胞上?并且,为什么他们会在稍后重新加载时恢复?我认为重用标识符可能是原因,但是在第一次加载时它们仍然被分配了该标识符,所以这应该无关紧要,是吗?
编辑:我认为100px高度来自我的故事板中原型单元格的行高,好像我将其更改为101px,前三个单元格最初为101px。 / p>
编辑:以下是我用来设置图片的代码,虽然这部分工作正常,但它的使用值不正确:
UIImage *cappedBG;
float cellHeight = cell.contentView.frame.size.height;
if (cellHeight <= 51) {
cappedBG = [[UIImage imageNamed: @"bg50.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else if (cellHeight <= 101) {
cappedBG = [[UIImage imageNamed: @"bg100.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else if (cellHeight <= 151) {
cappedBG = [[UIImage imageNamed: @"bg150.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else if (cellHeight <= 201) {
cappedBG = [[UIImage imageNamed: @"bg200.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
} else {
cappedBG = [[UIImage imageNamed: @"bg250.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
}
答案 0 :(得分:4)
你不能依赖tableView:cellForRowAtIndexPath:
中单元格的框架。您在该方法中配置的单元格框架将在代码从此方法返回后设置。
您获得的值不是该特定行的实际高度。从刚刚出列的单元格中获得高度。如果没有单元格出列,则使用刚刚创建的单元格的高度。 100可能是故事板/笔尖中单元格的高度。
此高度与将显示的单元格的高度无关。
由于您已经计算了tableView:heightForRowAtIndexPath:
中的行高,请使用此值。
float cellHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];
if (cellHeight <= 51) {
cappedBG = [[UIImage imageNamed: @"bg50.png"] resizableImageWithCapInsets: UIEdgeInsetsMake(25, 25, 25, 25) resizingMode: UIImageResizingModeStretch];
...
答案 1 :(得分:1)
你不应该在cellForRowAtIndexPath中进行单元格的布局。
执行此操作的最佳方法是使用所需的所有UI元素创建UITableViewCell子类。
然后在子类中,您可以覆盖- (void)layoutSubviews
。
通过这种方式,您可以将所有内容分开,而不是将所有内容放在视图控制器中。
答案 2 :(得分:1)
目前,在查看您的问题之后,我认为您在使用不同的单元格高度时遇到问题(滚动时)。我相信你没有在heightForRowAtIndexPath中给出正确的值。
以下是我编写的简单代码。此代码在表格中显示20行,而备用行具有不同的大小。(我使用了不同的颜色来区分)
#pragma mark - TableView DataSource Methods
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row %2 == 0) return 50;
else return 100;
}
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *stringCellIdentifier = @"BookOutVehicleCell";
UITableViewCell *tableViewCell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:stringCellIdentifier];
if (tableViewCell == nil)
tableViewCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:stringCellIdentifier] autorelease];
if(indexPath.row %2 == 0) tableViewCell.contentView.backgroundColor = [UIColor redColor];
else tableViewCell.contentView.backgroundColor = [UIColor greenColor];
return tableViewCell;
}
#pragma mark - TableView Delegate Methods
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
这是输出。
在这种情况下,即使我们上下滚动tableview,行高也不会改变。
希望这会有所帮助。抱歉,如果我误解了你的问题。如果你提供一个代码片段会很好。它会让我们更好地了解这个问题。
修改强> 根据我对该问题的理解,您为每个行/单元格获得了正确的高度,但是您在单元格中使用了一个imageview,它将根据单元格的高度显示不同的图像。检查以下内容是否适用于您:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *stringCellIdentifier = @"BookOutVehicleCell";
UITableViewCell *tableViewCell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:stringCellIdentifier];
if (tableViewCell == nil)
tableViewCell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:stringCellIdentifier] autorelease];
//Check your height here and use appropriate image
if(cell.contentView.frame.size.height <100)
{
image = "xxx.png";
}
else
if(cell.contentView.frame.size.height >=100 && cell.contentView.frame.size.height <200)
{
image = "yyy.png";
}
}
感谢。