0

StackOverflowの善良な人々の助けを借りて、私はこれらの2つの方法を持っています:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault)
            reuseIdentifier:@"business"];

    NSString *comment = [[items_array objectAtIndex:[indexPath row]] objectForKey:(@"comment")];

    NSLog(businessPrivacy);
    // FIND IF THE BUSINESS PLAN IS PRIVATE OR NOT.

        CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f); 

        CGSize size = [comment sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap]; 

        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, MAX(size.height, 44.0f) + 20.0f)]; 
        label.numberOfLines = 0; 
        label.lineBreakMode = UILineBreakModeWordWrap; 
        label.text = comment;  

        [cell.contentView addSubview:label];        

    return cell;
}

//Cell size for word wrapping.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{    
    NSString *comment = [[items_array objectAtIndex:[indexPath row]] objectForKey:(@"comment")];

    CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f); 

    CGSize size = [comment sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap]; 

    CGFloat height = MAX(size.height, 44.0f);

    return height + (10 * 2);
}

それらの効果は、デフォルトのフォントサイズからフォントサイズを縮小し、テキストの長さに関係なく、コメントのテキスト全体に動的にサイズ変更してALMOSTに合わせるというものです。

私が混乱しているのは、両方のメソッドに同じコードがいくつかあり、実際にどのように表示されるかわからないことです。両方のメソッドが呼び出されていることは知っていますが、正しく機能するようにどこにあるべきかわかりません。

アドバイスをよろしくお願いします。

4

3 に答える 3

3

両方で必要なようです。あなたがそれを理解できるように、私はあなたのコードをコメントで書き直しました:

//This function is used to create the cell and the content of the cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{   
    //Here you are allocating a new cell with a reuse identifier.  This is only needed if
    //you plan on reusing the cells and using [tableView dequeueReusableCellWithIdentifier:cellIdentifier]
    //Reusable cells will save you some memory and make your tableview work more smoothly,
    //however here you are not selecting from the reusable pool, and are instead making a new cell each time
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleDefault)
            reuseIdentifier:@"business"];

    //This is pulling the text for the comment, it is obviously necessary
    NSString *comment = [[items_array objectAtIndex:[indexPath row]] objectForKey:(@"comment")];

    NSLog(businessPrivacy);
    // FIND IF THE BUSINESS PLAN IS PRIVATE OR NOT.

    // This is creating a constraint size for the label you are making
    CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f); 

    // This is determining the size that you will need for the label based on the comment
    // length and the contraint size
    CGSize size = [comment sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap]; 

    //  Here you are creating your label and initializing it with the frame that you have
    //  determined by your size calculations above
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, MAX(size.height, 44.0f) + 20.0f)];

    // setting up the label properties
    label.numberOfLines = 0;
    label.lineBreakMode = UILineBreakModeWordWrap; 
    label.text = comment;  

    // adding the label view to the cell that you have created
    [cell.contentView addSubview:label];        

    // return the cell for the table view
    return cell;
}

//Cell size for word wrapping.
//This method will determine how tall each row needs to be.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    //Here you are getting the comment again.  This is necessary to determine how tall you need
    //the cell to be    
    NSString *comment = [[items_array objectAtIndex:[indexPath row]] objectForKey:(@"comment")];

    // Again you are getting the constraints because you are going to us this size
    // to constrain the height of the cell just like you determined the size for the label.
    CGSize constraint = CGSizeMake(320 - (10 * 2), 20000.0f); 

    // Again, determining the size that we will need for the label, because it will drive
    // the height of the cell
    CGSize size = [comment sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap]; 

    //  Finally, we can determine the height for the cell!
    CGFloat height = MAX(size.height, 44.0f);

    //  return the height, which is the height of the label plus some extra space to make
    //  it look good.
    return height + (10 * 2);
}

したがって、基本的に、cellForRow...関数はセルのコンテンツを作成し、heightForRow...関数は高さを決定します。cell関数はセルのコンテンツのみを作成し、height関数は行の高さを作成し、コメント、制約、サイズはすべてlabelセルコンテンツのサイズを決定する上で重要であるため、両方の情報が必要です。セルの高さ。

于 2012-08-07T20:09:47.020 に答える
1

したがってheightForRowAtIndexPath、その名前が示すように、セルの高さのみを扱います。つまり、その関数の戻り値(a CGFloat)は、指定されたインデックスパスでのセルの高さです。

cellForRowAtIndexPath一方、すべてのサブビューを含む実際のセルを設定します。何が起こるかというと、いくつかのセルには5行がUILabelあり、いくつかには1行があるとします。次に、のセルのサイズを調整する必要がありheightForRowAtIndexPathますが、同時に、UILabelのセル内のサイズも調整する必要がありますcellForRowAtIndexPath。後者は自動的には発生しません。あなたはあなた自身の両方の世話をする必要があります。

于 2012-08-07T20:04:34.393 に答える
1

同じコードを2回以上作成する必要がある場合は、重複するコードをメソッドまたは関数に抽出することを検討する必要があります。しかし、私たちが対処しなければならない他のいくつかの問題があります。

コード全体で数値を繰り返す必要がないように、いくつかの定数を宣言しましょう。

static const CGFloat kLabelMargin = 10.0f;
static const CGFloat kLabelWidth = 320.0f - 2.0f * kLabelMargin;

両方の方法で複製した1行は、行のコメントを検索します。それを行うためのメソッドを作成しましょう:

- (NSString *)commentForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [[items_array objectAtIndex:[indexPath row]] objectForKey:@"comment"];
}

他の重複したコードは行の高さを計算するので、それを返す関数を作成しましょう:

static CGFloat heightForComment(NSString *comment) {
    CGSize constraint = CGSizeMake(kLabelWidth, 20000.0f);
    CGSize size = [comment sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
    return MAX(size.height, 44.0f) + 2.0f * kLabelMargin;
}

tableView:heightForRowAtIndexPath:これで、メソッドを書き直すことができます。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return heightForComment([self commentForRowAtIndexPath:indexPath]);
}

最後に、メソッドを書き直してみましょうtableView:cellForRowAtIndexPath:。(メモリの浪費を避けるために)セルを適切に再利用し、作成した新しいメソッドと関数を使用するようにします。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *const kReuseIdentifier = @"business";
    static const NSInteger kLabelTag = 1;

    NSLog(@"%@", businessPrivacy);
    // FIND IF THE BUSINESS PLAN IS PRIVATE OR NOT.

    NSString *comment = [self commentForRowAtIndexPath:indexPath];
    CGRect labelFrame = CGRectMake(0, 0, kLabelWidth, heightForComment(comment));

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kReuseIdentifier];
    UILabel *label;
    if (cell) {
        label = (UILabel *)[cell.contentView viewWithTag:kLabelTag];
        label.frame = labelFrame;
    } else {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kReuseIdentifier];
        label = [[UILabel alloc] initWithFrame:labelFrame];
        label.tag = kLabelTag;
        label.numberOfLines = 0;
        label.lineBreakMode = UILineBreakModeWordWrap;
        [cell.contentView addSubview:label];
    }

    label.text = comment;

    return cell;
}
于 2012-08-07T20:14:19.407 に答える