2

上部に 2 つの比較的静的なセルを含む TableView を表示するアプリがあり、その後にラベルとセグメント化されたコントロールを含む一連のカスタム セルが続きます。これらのセルは、ラベル内のテキストの量に基づいて高さを変える必要があります。

cellForRowAtIndexPath で必要なセルの高さを計算し、その値を配列に格納してから、その配列の値を heightForRowAtIndexPath で使用しています。ただし、heightForRowAtIndexPath が最初に呼び出されているように見えるため、行の高さはすべて 0/nil です。

セルを構成する前にセルの高さを知る必要がある場合、セルの特定のコンテンツに基づいて行の高さを指定するにはどうすればよいですか?

cellForRowAtIndexPath からのスニペット:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger currentIndex = indexPath.item;
    if (indexPath.item == 0){
        static NSString *CellIdentifier = @"MeasurementCell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
        [self.cellHeightList insertObject:[NSNumber numberWithInt:44] atIndex:currentIndex];
        return cell;
    } else if (indexPath.item == 1){
        if (self.dataController.isScoreAvailable){
            static NSString *CellIdentifier = @"ScoreCell";
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
            [self.cellHeightList insertObject:[NSNumber numberWithInt:46] atIndex:currentIndex];
            return cell;
        } else {
            static NSString *CellIdentifier = @"ScoreCell";
            UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
            cell.accessoryType = UITableViewCellAccessoryNone;
            [self.cellHeightList insertObject:[NSNumber numberWithInt:0] atIndex:currentIndex];
            return cell;
        }
    } else if (indexPath.item > 1){
        NSInteger labelWidth = [UIScreen mainScreen].applicationFrame.size.width - 140; //80 for segment + 3*20 for margins & spacing
        CGSize maxSize = CGSizeMake(labelWidth, MAXFLOAT);
        CGSize labelSize;

        static NSString *CellIdentifier = @"QuestionCell";
        InterviewQuestionCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
        InterviewQuestion *questionAtIndex = [self.dataController objectInListAtIndex:(indexPath.item-2)];
        cell.questionLabel.text = questionAtIndex.questionText;
        labelSize = [cell.questionLabel.text sizeWithFont:[UIFont systemFontOfSize:12.0] constrainedToSize:maxSize lineBreakMode:NSLineBreakByWordWrapping];
        CGRect labelFrame = CGRectMake(0, 0, labelWidth, labelSize.height);
        cell.questionLabel.frame = labelFrame;
        cell.questionLabel.numberOfLines = 0;
        cell.answerControl.selectedSegmentIndex = questionAtIndex.answer;
        cell.answerControl.tag = indexPath.item;
        [self.cellHeightList insertObject:[NSNumber numberWithInt:labelSize.height] atIndex:currentIndex];
        return cell;
    }
    return nil;
}

heightForRowAtIndexPath からのコード:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger currentIndex = indexPath.item;
    return [[self.cellHeightList objectAtIndex:currentIndex] integerValue];
}

ありがとう!

4

3 に答える 3

2

まず、indexPath で「item」を使用せず、「row」を使用していることを確認してください。アイテムは、UITableViewではなくUICollectionViewで使用されていると思います。次に、セルを手元に置かずにセルのサイズを計算する方法が必要です。tableView には特定の幅があるため、それに基づいて必要な高さを計算できる場合があります。この計算を heightForRowAtIndexPath: に配置します (これが集中している場合は、キャッシュします)。

具体的には、 cellForRowAtIndexPath ではなく、 heightForRowAtIndexPath: に次のコードを配置します。

NSInteger labelWidth = [UIScreen mainScreen].applicationFrame.size.width - 140;
CGSize maxSize = CGSizeMake(labelWidth, MAXFLOAT);
CGSize labelSize;

また、UIScreen を使用する代わりに、単純に tableView の幅を使用すると、コードの結合が緩くなります。

于 2013-09-07T13:25:50.047 に答える