cellForRowAtIndexPath在加载时将单元格视为不同的高度,然后重新加载?

时间:2013-03-19 14:05:54

标签: ios objective-c uitableview heightforrowatindexpath

前言:这是一个非常抽象的问题。

我在UITableView中有一些单元格使用不同的图像,具体取决于单元格的高度(以50px为增量,从50px到高达1000px)。我遇到一个奇怪的问题,当应用程序首次加载时,cellForRowAtIndexPath报告前三个单元格(无论是否所有三个单元格都是onscree)的高度为100px,然后当我向下滚动并备份时再次,他们的高度恢复到正确的值。屏幕上没有高度变化,只有使用的图像发生了变化,cell.frame.size.height语句中NSLog的值也没有变化。

我一直在登录heightForRowAtIndexPathcellForRowAtIndexPath,我可以在离开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];
} 

3 个答案:

答案 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];

}

这是输出。

enter image description here

在这种情况下,即使我们上下滚动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";
       }


    }

感谢。