Làm cách nào để tôi bọc văn bản trong UITableViewCell mà không có ô tùy chỉnh


151

Đây là trên iPhone 0S 2.0. Câu trả lời cho 2.1 cũng tốt, mặc dù tôi không biết về bất kỳ sự khác biệt nào liên quan đến các bảng.

Cảm giác như có thể lấy văn bản để bọc mà không cần tạo một ô tùy chỉnh, vì một mặc định UITableViewCellchứa một UILabel. Tôi biết tôi có thể làm cho nó hoạt động nếu tôi tạo một ô tùy chỉnh, nhưng đó không phải là điều tôi đang cố gắng đạt được - tôi muốn hiểu tại sao cách tiếp cận hiện tại của tôi không hiệu quả.

Tôi đã nhận ra rằng nhãn được tạo theo yêu cầu (vì ô hỗ trợ truy cập văn bản và hình ảnh, do đó, nó không tạo chế độ xem dữ liệu cho đến khi cần thiết), vì vậy nếu tôi làm điều gì đó như thế này:

cell.text = @""; // create the label
UILabel* label = (UILabel*)[[cell.contentView subviews] objectAtIndex:0];

sau đó tôi nhận được một nhãn hợp lệ, nhưng cài đặt numberOfLinestrên đó (và lineBreakMode) không hoạt động - Tôi vẫn nhận được văn bản một dòng. Có rất nhiều chiều cao UILabelcho văn bản hiển thị - Tôi chỉ trả về một giá trị lớn cho chiều cao trong heightForRowAtIndexPath.

Câu trả lời:


277

Đây là một cách đơn giản hơn và nó hiệu quả với tôi:

Bên trong cellForRowAtIndexPath:chức năng của bạn . Lần đầu tiên bạn tạo ô của mình:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

Bạn sẽ nhận thấy rằng tôi đặt số lượng dòng cho nhãn là 0. Điều này cho phép nó sử dụng bao nhiêu dòng mà nó cần.

Phần tiếp theo là xác định mức độ lớn của bạn UITableViewCell, vì vậy hãy thực hiện điều đó trong heightForRowAtIndexPathchức năng của bạn :

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

    return labelSize.height + 20;
}

Tôi đã thêm 20 vào chiều cao ô được trả về vì tôi thích một bộ đệm nhỏ xung quanh văn bản của mình.


17
Bạn không cần phải đặt cell.textLabel.numberOfLines của bạn thành một số cao tùy ý. Đặt nó thành 0 có nghĩa là "càng nhiều dòng cần hiển thị."
mmc

Cảm ơn, tôi sẽ chỉnh sửa bài viết của mình tối nay sau khi tôi có cơ hội xác minh nó trong dự án của riêng tôi.
Tim Rupe

1
Đặt số lượng dòng thành 0 hoạt động tốt (số lượng dòng cần hiển thị)
prakash

1
cagreen: Hóa ra tôi có thể sao chép cái này, nhưng chỉ khi tôi sử dụng iPhone OS 3.0 trong trình giả lập. Khi tôi sử dụng 3.1+, kích thước thay đổi kích thước của chi tiết phù hợp với sizeWithFont. Vì vậy, phương pháp của Tim hoạt động rất tốt - chỉ trong 3,1+ (có thể do lỗi / lỗi không hoạt động trong kết xuất ô mặc định 3.0). Đối với bản ghi, tôi đang sử dụng lề trên / dưới dọc là 12 (mỗi), kích thước nhãn văn bản chi tiết là (188.0, CGFLOAT_MAX) và đậmSystemFontOfSize 15.
Joe D'Andrea

17
UILineBreakModeWordWrap không được dùng trong iOS 6. Thay vào đó, hãy sử dụng NSLineBreakByWordWrapping.
Ethan Allen

16

Cập nhật câu trả lời của Tim Rupe cho iOS7:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
    cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];

    NSAttributedString *attributedText =
        [[NSAttributedString alloc]
            initWithString:cellText
            attributes:@
            {
                NSFontAttributeName: cellFont
            }];
    CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(tableView.bounds.size.width, CGFLOAT_MAX)
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                               context:nil];
    return rect.size.height + 20;
}

3

Một nhận xét / câu trả lời ngắn gọn để ghi lại trải nghiệm của tôi khi tôi gặp vấn đề tương tự. Mặc dù sử dụng các ví dụ mã, chiều cao của ô xem bảng đang điều chỉnh, nhưng nhãn bên trong ô vẫn không điều chỉnh chính xác - giải pháp là tôi đang tải ô của mình từ tệp NIB tùy chỉnh, xảy ra sau khi điều chỉnh chiều cao của ô.

Và tôi đã có các cài đặt của mình bên trong tệp NIB để không ngắt văn bản và chỉ có 1 dòng cho nhãn; cài đặt tệp NIB đã ghi đè cài đặt tôi đã điều chỉnh bên trong mã.

Bài học tôi học được là đảm bảo luôn luôn ghi nhớ trạng thái của các vật thể tại từng thời điểm - chúng có thể chưa được tạo ra! ... hth ai đó xuống dòng.


2

Nếu chúng ta chỉ thêm văn bản trong UITableViewô, chúng ta chỉ cần hai đại biểu để làm việc (không cần thêm UILabels)

1) cellForRowAtIndexPath

2) heightForRowAtIndexPath

Giải pháp này hiệu quả với tôi: -

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;

    [cell setSelectionStyle:UITableViewCellSelectionStyleGray]; 
    cell.textLabel.text = [mutArr objectAtIndex:indexPath.section];
    NSLog(@"%@",cell.textLabel.text);

    cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow.png" ]];

    return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{  
    CGSize labelSize = CGSizeMake(200.0, 20.0);

    NSString *strTemp = [mutArr objectAtIndex:indexPath.section];

    if ([strTemp length] > 0)
        labelSize = [strTemp sizeWithFont: [UIFont boldSystemFontOfSize: 14.0] constrainedToSize: CGSizeMake(labelSize.width, 1000) lineBreakMode: UILineBreakModeWordWrap];

    return (labelSize.height + 10);
}

Ở đây, chuỗi mutArrlà một mảng có thể thay đổi mà từ đó tôi nhận được dữ liệu của mình.

EDIT: - Đây là mảng mà tôi đã lấy.

mutArr= [[NSMutableArray alloc] init];

[mutArr addObject:@"HEMAN"];
[mutArr addObject:@"SUPERMAN"];
[mutArr addObject:@"Is SUPERMAN powerful than HEMAN"];
[mutArr addObject:@"Well, if HEMAN is weaker than SUPERMAN, both are friends and we will never get to know who is more powerful than whom because they will never have a fight among them"];
[mutArr addObject:@"Where are BATMAN and SPIDERMAN"];

2

Bây giờ các bảng xem có thể có các ô tự kích thước. Đặt chế độ xem bảng lên như sau

tableView.estimatedRowHeight = 85.0 //use an appropriate estimate tableView.rowHeight = UITableViewAutomaticDimension

Tham khảo Apple


0

Tôi sử dụng các giải pháp sau đây.

Dữ liệu được cung cấp riêng trong một thành viên:

-(NSString *)getHeaderData:(int)theSection {
    ...
    return rowText;
}

Việc xử lý có thể dễ dàng thực hiện trong cellForRowAtIndexPath. Xác định ô / xác định phông chữ và gán các giá trị này cho "ô" kết quả. Lưu ý rằng giá trị numberoflinesđược đặt thành "0", có nghĩa là lấy những gì cần thiết.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    cell.textLabel.text= [self getRowData:indexPath.section];
    cell.textLabel.font = cellFont;
    cell.textLabel.numberOfLines=0;
    return cell;
}

Trong heightForRowAtIndexPath, tôi tính toán độ cao của văn bản được bọc. Kích thước mã hóa sẽ liên quan đến chiều rộng của ô của bạn. Đối với iPad, giá trị này sẽ là 1024. Đối với iPhone en iPod 320.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    CGSize boundingSize = CGSizeMake(1024, CGFLOAT_MAX);
    CGSize requiredSize = [[self getRowData:indexPath.section] sizeWithFont:cellFont constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
    return requiredSize.height;    
}

0

Tôi thấy điều này khá đơn giản và dễ hiểu:

[self.tableView setRowHeight:whatEvereight.0f];

ví dụ:

[self.tableView setRowHeight:80.0f];

Điều này có thể hoặc không thể là cách tiếp cận tốt nhất / tiêu chuẩn để làm như vậy, nhưng nó đã hoạt động trong trường hợp của tôi.


Theo tôi hiểu, thuộc tính rowHeight đặt chiều cao cố định sẽ được sử dụng cho tất cả các ô trong chế độ xem bảng. Sử dụng rowHeight sẽ tốt hơn cho hiệu suất trong các bảng lớn, nhưng nếu bạn cần chiều cao của mỗi ô thay đổi dựa trên nội dung của nó thì có vẻ như phương thức tableView: heightForRowAtIndexPath: phải được sử dụng.
jk7

0

Hãy thử mã của tôi trong nhanh chóng. Mã này cũng sẽ hoạt động cho UILabels bình thường.

extension UILabel {
    func lblFunction() {
        //You can pass here all UILabel properties like Font, colour etc....
        numberOfLines = 0
        lineBreakMode = .byWordWrapping//If you want word wraping
        lineBreakMode = .byCharWrapping//If you want character wraping
    }
}

Bây giờ gọi đơn giản như thế này

cell.textLabel.lblFunction()//Replace your label name 

-1

Tôi nghĩ rằng đây là một giải pháp tốt hơn và ngắn hơn. Chỉ cần định dạng UILabel( textLabel) của ô để tự động tính toán chiều cao bằng cách chỉ định sizeToFitvà mọi thứ sẽ ổn.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    cell.textLabel.text = @"Whatever text you want to put here is ok";
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    [cell.textLabel sizeToFit];

    return cell;
}

-2

Tôi không nghĩ rằng bạn có thể thao túng một cơ sở UITableViewCell'stư nhân UILabelđể làm điều này. Bạn có thể thêm một mới UILabelvào tế bào thân và sử dụng numberOfLinesvới sizeToFitkích thước nó một cách thích hợp. Cái gì đó như:

UILabel* label = [[UILabel alloc] initWithFrame:cell.frame];
label.numberOfLines = <...an appriate number of lines...>
label.text = <...your text...>
[label sizeToFit];
[cell addSubview:label];
[label release];
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.