cellForRowAtIndexPath和heightForRowAtIndexPath之间的关系是什么

时间:2014-03-20 15:43:51

标签: ios objective-c uitableview

我在哪里使用heightForRowAtIndexPath中计算的高度?

对不起,如果文字不太清楚,这是希伯来语:) 看,第二个细胞有两条线?所以我希望细胞更高。 所以,我根据文本计算了单元格的高度,然后去设置单元格。例如,背景应该与细胞本身的大小一样,并且它们都混合在一起......

enter image description here

以下是代码:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    AnswerObject* answer = self.question.answers[indexPath.row];
    CGFloat height = [AnswerTableViewCell answerCellHeight:answer];
    return height;
}

-(AnswerTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    AnswerTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[AnswerTableViewCell alloc] init];
    }

    AnswerObject* answer = self.question.answers[indexPath.row];

    [cell setupAnswerTableViewCell:self.question answer:answer row:indexPath.row];

    return cell;
}

AnswerTableViewCell:

- (id)init
{
    self = [super init];
    if (self) {

//        self.frame = CGRectMake(0, 0, 280, 77);

        self.backgroundColor = [UIColor clearColor];
        self.contentView.backgroundColor = [UIColor clearColor];

        self.answerLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 10, self.frame.size.width-20, self.frame.size.height)];
        self.answerLabel.numberOfLines = 20;
        self.answerLabel.textColor = [UIColor whiteColor];
        self.answerLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:16];
        self.answerLabel.textAlignment = NSTextAlignmentRight;
        self.answerLabel.lineBreakMode = NSLineBreakByWordWrapping;

        self.answerToggle = [[UIButton alloc]initWithFrame:CGRectMake(self.frame.size.width-50, 23, 30, 30)];

        self.backgroundImage = [[UIImageView alloc]init];
        self.backgroundImage.frame = self.bounds;

        [self addSubview:self.answerLabel];
        [self addSubview:self.answerToggle];
        [self addSubview:self.backgroundImage];
    }
    return self;
}


-(void)setupAnswerTableViewCell:(QuestionObject*)question
                         answer:(AnswerObject*)answer
                            row:(NSInteger)row{
    self.question = question;
    self.answer = answer;
    self.row = row;

    CGSize labelSize = [answer.answerText sizeWithFont:self.answerLabel.font constrainedToSize:CGSizeMake(self.answerLabel.frame.size.width, 100000) lineBreakMode:self.answerLabel.lineBreakMode];

//    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, labelSize.height + 20);

    self.answerLabel.frame = CGRectMake(self.answerLabel.frame.origin.x, self.answerLabel.frame.origin.y, self.answerLabel.frame.size.width, labelSize.height);

    self.answerLabel.text = answer.answerText;

    [self.answerToggle addTarget:self
                          action:@selector(flip:)
                forControlEvents:UIControlEventTouchDown];


    self.answerToggle.tag = [answer.answerID intValue];

    if (self.row == 0) {
        self.backgroundImage.image = [UIImage imageNamed:@"List_Top_Item_Not_Selected_612x113px.png"];
    }
    else if (self.row == ([self.question.answers count] - 1)){
        self.backgroundImage.image = [UIImage imageNamed:@"List_Bottom_Item_Not_Selected_612x113px.png"];
    }
    else{
        self.backgroundImage.image = [UIImage imageNamed:@"List_Item_Not_Selected_612x113px.png"];
    }

}

+(CGFloat)answerCellHeight:(AnswerObject*)answer{
    CGSize labelSize = [answer.answerText sizeWithFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:16] constrainedToSize:CGSizeMake(280, 100000) lineBreakMode:NSLineBreakByWordWrapping];

    return labelSize.height + 20;
}

4 个答案:

答案 0 :(得分:1)

heightForRowAtIndexPath是您实现的委托方法,您只需要返回每个单元格所需高度的值,TableView将“使用”该值并设置单元格高度本身。

cellForRowAtIndexPath以递归调用的方式布置每个单元格的内容(设置标签,每个单元格的imageViews等),就在它们出现在屏幕上之前。

考虑这个简单的heightForRowAtIndexPath:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    return 50;
}

如果这是您的实现,则tableview中的每个单元格都会自动将其高度设置为50磅。

您无需再做任何其他事情......只需返回每个单元格所需的高度值即可。

这只是一个简单的例子,您可以在heightForRowAtIndexPath中放置一些条件逻辑,使每个第二个单元格(例如)的高度不同。

答案 1 :(得分:1)

heightForRowAtIndexPath UITableView向数据源询问它应该准备的单元格高度,然后才能填充其内容。

tableView然后在两个单元格之间分配那么多的大小/空间。 通过那里的单元格仍然需要由数据源给出,这是在cellForRowIndexPath方法中完成的。

  

修改

当您返回单元格的自定义高度时,您的框架会重叠。但不在单元格中使用它们并将子视图初始化为其他值。

您可以使用layoutSubviews来获得正确的高度并正确布置视图..或者在setupAnswerCell方法中使用额外的参数高度,然后传递自定义高度并在那里布置项目。< / p>

答案 2 :(得分:1)

以下是示例代码:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    int ix = indexPath.row;
    if ([NSNull null] == self.heights[ix]) {
        NSString* s = self.trivia[ix];
        CGFloat h = [self cellHeightForLabelString:s];
        self.heights[ix] = @(h);
    }
    return [self.heights[ix] floatValue];
}

我不知道我会被问到任何给定行的高度的时间和次数,并且计算高度需要一点时间,所以我保留了所有高度的数组,这开始了out作为NSNull对象的数组。如果我已经计算了所请求行的高度,我会将其返回。如果我没有,我会计算它,存储它,然后然后我将它返回。

然后,运行时将每行设置为我请求的高度。

答案 3 :(得分:0)

你没有使用高度,你只是提供它。表视图使用它来确定内容的总高度以及如何在该索引路径中显示单元格。细胞应该预期在规定的高度布置/适当调整到该高度。


当您在代码中设置单元格而不使用自动布局时,您应该设置单元格的框架。它设置它并不重要,但你应该设置它,然后相对于它设置所有子视图的帧。然后,您需要为所有子视图添加自动调整大小规则。在您的情况下,两个子视图都应指定灵活的宽度和高度规则。

添加这些东西以确保正确布置细胞内容。