Come posso avvolgere il testo in un UITableViewCell senza una cella personalizzata


151

Questo è su iPhone 0S 2.0. Anche le risposte per 2.1 vanno bene, anche se non sono a conoscenza di differenze riguardo alle tabelle.

Sembra che dovrebbe essere possibile ottenere il testo da avvolgere senza creare una cella personalizzata, poiché a UITableViewCellcontiene un UILabelvalore predefinito. So che posso farlo funzionare se creo una cella personalizzata, ma non è quello che sto cercando di ottenere: voglio capire perché il mio approccio attuale non funziona.

Ho capito che l'etichetta è stata creata su richiesta (poiché la cella supporta l'accesso al testo e all'immagine, quindi non crea la vista dati fino a quando non è necessario), quindi se faccio qualcosa del genere:

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

quindi ottengo un'etichetta valida, ma l'impostazione numberOfLinessu quella (e lineBreakMode) non funziona - ricevo ancora testo a riga singola. C'è molta altezza nella UILabelvisualizzazione del testo: sto solo restituendo un valore elevato per l'altezza heightForRowAtIndexPath.

Risposte:


277

Ecco un modo più semplice e funziona per me:

All'interno della tua cellForRowAtIndexPath:funzione. La prima volta che crei la tua cella:

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];
}

Noterai che ho impostato il numero di righe per l'etichetta su 0. Ciò consente di utilizzare tutte le righe necessarie.

La parte successiva è specificare quanto UITableViewCellsarà grande , quindi fallo nella tua heightForRowAtIndexPathfunzione:

- (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;
}

Ho aggiunto 20 alla mia altezza di cella restituita perché mi piace un piccolo buffer attorno al mio testo.


17
Non è necessario impostare cell.textLabel.numberOfLines su un numero arbitrariamente alto. Impostandolo su 0 significa "tutte le righe necessarie per visualizzare".
mmc

Grazie, modificherò il mio post stasera dopo che avrò la possibilità di verificarlo nel mio progetto.
Tim Rupe,

1
L'impostazione del numero di righe su 0 funziona
correttamente

1
cagreen: A quanto pare posso replicarlo, ma solo se uso iPhone OS 3.0 nel simulatore. Quando uso 3.1+, il ridimensionamento di detailTextLabel corrisponde a quello di sizeWithFont bene. Quindi il metodo di Tim funziona davvero bene - solo per 3.1+ (probabilmente a causa di un bug / malfunzionamento nel rendering delle celle predefinito 3.0). Per la cronaca, sto usando un margine verticale superiore / inferiore di 12 (ciascuno), una dimensione dell'etichetta di testo di dettaglio di (188.0, CGFLOAT_MAX) e un grassetto SystemFontOfSize 15.
Joe D'Andrea,

17
UILineBreakModeWordWrap è obsoleto in iOS 6. Utilizzare invece NSLineBreakByWordWrapping.
Ethan Allen,

16

Aggiornamento della risposta di Tim Rupe per 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

Un breve commento / risposta per registrare la mia esperienza quando ho avuto lo stesso problema. Nonostante si usassero gli esempi di codice, l'altezza della cella della vista tabella si stava adeguando, ma l'etichetta all'interno della cella non stava ancora regolando correttamente - la soluzione era che stavo caricando la mia cella da un file NIB personalizzato, che si verifica dopo che l'altezza della cella è stata regolata.

E avevo le mie impostazioni all'interno del file NIB per non avvolgere il testo e avevo solo 1 riga per l'etichetta; le impostazioni del file NIB stavano sovrascrivendo le impostazioni che ho regolato all'interno del codice.

La lezione che ho preso è stata quella di assicurarmi di tenere sempre presente lo stato degli oggetti in ogni momento: potrebbero non essere ancora stati creati! ... hth qualcuno lungo la linea.


2

Se vogliamo aggiungere solo testo nella UITableViewcella, abbiamo bisogno di solo due delegati con cui lavorare (non è necessario aggiungere ulteriori UILabels)

1) cellForRowAtIndexPath

2) heightForRowAtIndexPath

Questa soluzione ha funzionato per me: -

-(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);
}

Qui la stringa mutArrè un array mutabile da cui sto ottenendo i miei dati.

EDIT: - Ecco l'array che ho preso.

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

Ora le visualizzazioni di tabella possono avere celle auto-dimensionanti. Impostare la vista tabella come segue

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

Riferimento Apple


0

Uso le seguenti soluzioni.

I dati sono forniti separatamente in un membro:

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

La gestione può essere facilmente eseguita cellForRowAtIndexPath. Definire la cella / definire il carattere e assegnare questi valori alla "cella" di risultato. Si noti che numberoflinesè impostato su "0", che significa prendere ciò che è necessario.

- (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;
}

In heightForRowAtIndexPath, calcolo le altezze del testo avvolto. Le dimensioni del corpo devono essere correlate alla larghezza della tua cella. Per iPad questo deve essere 1024. Per iPhone e 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

Ho trovato questo per essere abbastanza semplice e diretto Avanti:

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

per esempio:

[self.tableView setRowHeight:80.0f];

Questo potrebbe essere o meno l'approccio migliore / standard per farlo, ma ha funzionato nel mio caso.


A quanto ho capito, la proprietà rowHeight imposta un'altezza fissa che verrà utilizzata per tutte le celle nella vista tabella. L'uso di rowHeight è migliore per le prestazioni in tabelle di grandi dimensioni, ma se è necessario che l'altezza di ciascuna cella vari in base al suo contenuto, allora sembra tableView: heightForRowAtIndexPath: il metodo deve essere utilizzato.
jk7,

0

Prova il mio codice rapidamente. Questo codice funzionerà anche con UILabels normali.

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
    }
}

Adesso chiama semplicemente così

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

-1

Penso che questa sia una soluzione migliore e più breve. Basta formattare il UILabel( textLabel) della cella per calcolare automaticamente l'altezza specificando sizeToFite tutto dovrebbe andare bene.

- (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

Non penso che tu possa manipolare una base UITableViewCell'sprivata UILabelper farlo. Si potrebbe aggiungere un nuovo UILabelalla cella da soli e utilizzare numberOfLinescon sizeToFitle dimensioni in modo appropriato. Qualcosa di simile a:

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];
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.