Impostazione personalizzata UITableViewCells altezza

voti
209

Sto usando una consuetudine UITableViewCell che ha alcune etichette, bottoni e viste di immagini da visualizzare. C'è un'etichetta nella cella cui testo è un NSStringoggetto e la lunghezza della stringa può essere variabile. A causa di questo, non è possibile impostare un'altezza costante alla cella in UITableView's heightForCellAtIndexmetodo. L'altezza della cella dipende dall'altezza dell'etichetta che può essere determinata utilizzando il NSString's sizeWithFontmetodo. Ho provato ad usarlo, ma sembra che sto andando male da qualche parte. Come può essere aggiustato?

Ecco il codice utilizzato per l'inizializzazione della cella.

if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier])
{
    self.selectionStyle = UITableViewCellSelectionStyleNone;
    UIImage *image = [UIImage imageNamed:@dot.png];
    imageView = [[UIImageView alloc] initWithImage:image];
    imageView.frame = CGRectMake(45.0,10.0,10,10);

    headingTxt = [[UILabel alloc] initWithFrame:   CGRectMake(60.0,0.0,150.0,post_hdg_ht)];
    [headingTxt setContentMode: UIViewContentModeCenter];
    headingTxt.text = postData.user_f_name;
    headingTxt.font = [UIFont boldSystemFontOfSize:13];
    headingTxt.textAlignment = UITextAlignmentLeft;
    headingTxt.textColor = [UIColor blackColor];

    dateTxt = [[UILabel alloc] initWithFrame:CGRectMake(55.0,23.0,150.0,post_date_ht)];
    dateTxt.text = postData.created_dtm;
    dateTxt.font = [UIFont italicSystemFontOfSize:11];
    dateTxt.textAlignment = UITextAlignmentLeft;
    dateTxt.textColor = [UIColor grayColor];

    NSString * text1 = postData.post_body;
    NSLog(@text length = %d,[text1 length]);
    CGRect bounds = [UIScreen mainScreen].bounds;
    CGFloat tableViewWidth;
    CGFloat width = 0;
    tableViewWidth = bounds.size.width/2;
    width = tableViewWidth - 40; //fudge factor
    //CGSize textSize = {width, 20000.0f}; //width and height of text area
    CGSize textSize = {245.0, 20000.0f}; //width and height of text area
    CGSize size1 = [text1 sizeWithFont:[UIFont systemFontOfSize:11.0f]
                        constrainedToSize:textSize lineBreakMode:UILineBreakModeWordWrap];

    CGFloat ht = MAX(size1.height, 28);
    textView = [[UILabel alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,ht)];
    textView.text = postData.post_body;
    textView.font = [UIFont systemFontOfSize:11];
    textView.textAlignment = UITextAlignmentLeft;
    textView.textColor = [UIColor blackColor];
    textView.lineBreakMode = UILineBreakModeWordWrap;
    textView.numberOfLines = 3;
    textView.autoresizesSubviews = YES;

    [self.contentView addSubview:imageView];
    [self.contentView addSubview:textView];
    [self.contentView addSubview:webView];
    [self.contentView addSubview:dateTxt];
    [self.contentView addSubview:headingTxt];
    [self.contentView sizeToFit];

    [imageView release];
    [textView release];
    [webView release];
    [dateTxt release];
    [headingTxt release];
}

Questa è l'etichetta la cui altezza e larghezza stanno andando male:

textView = [[UILabel alloc] initWithFrame:CGRectMake(55.0,42.0,245.0,ht)];
È pubblicato 30/01/2009 alle 06:27
fonte dall'utente
In altre lingue...                            


9 risposte

voti
483

Il tuo UITableViewDelegatedovrebbe implementaretableView:heightForRowAtIndexPath:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [indexPath row] * 20;
}

Probabilmente si vorrà usare NSString's sizeWithFont:constrainedToSize:lineBreakMode:metodo per calcolare l'altezza di fila piuttosto che solo l'esecuzione di alcune matematica sciocca sul indexPath :)

Risposto il 30/01/2009 a 23:46
fonte dall'utente

voti
121

Se tutte le righe hanno la stessa altezza, basta impostare la rowHeightproprietà del UITableView, piuttosto che attuare il heightForRowAtIndexPath. Mela Documenti:

Ci sono implicazioni sulle prestazioni di utilizzare tableView: heightForRowAtIndexPath: invece di rowHeight. Ogni volta che viene visualizzata una vista tabella, chiama tableView: heightForRowAtIndexPath: sulla delegato per ciascuna delle righe, che può risultare in un significativo problema di prestazioni con viste tabella avente un gran numero di righe (circa 1000 o più).

Risposto il 19/01/2011 a 00:59
fonte dall'utente

voti
22

in un costume UITableViewCell -Controller aggiungere questo

-(void)layoutSubviews {  

    CGRect newCellSubViewsFrame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    CGRect newCellViewFrame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, self.frame.size.height);

    self.contentView.frame = self.contentView.bounds = self.backgroundView.frame = self.accessoryView.frame = newCellSubViewsFrame;
    self.frame = newCellViewFrame;

    [super layoutSubviews];
}

Nel UITableView -Controller aggiungere questo

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [indexPath row] * 1.5; // your dynamic height...
}
Risposto il 19/01/2010 a 14:26
fonte dall'utente

voti
17
#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 300.0f
#define CELL_CONTENT_MARGIN 10.0f

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath      *)indexPath;
{
   /// Here you can set also height according to your section and row
   if(indexPath.section==0 && indexPath.row==0)
   {
     text=@"pass here your dynamic data";

     CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

     CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE]      constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

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

     return height + (CELL_CONTENT_MARGIN * 2);
   }
   else
   {
      return 44;
   }
}

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell;
    UILabel *label = nil;

    cell = [tv dequeueReusableCellWithIdentifier:@"Cell"];
    if (cell == nil)
    {
       cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"Cell"];
    }
    ********Here you can set also height according to your section and row*********
    if(indexPath.section==0 && indexPath.row==0)
    {
        label = [[UILabel alloc] initWithFrame:CGRectZero];
        [label setLineBreakMode:UILineBreakModeWordWrap];
        [label setMinimumFontSize:FONT_SIZE];
        [label setNumberOfLines:0];
        label.backgroundColor=[UIColor clearColor];
        [label setFont:[UIFont systemFontOfSize:FONT_SIZE]];
        [label setTag:1];

        // NSString *text1 =[NSString stringWithFormat:@"%@",text];

        CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        if (!label)
        label = (UILabel*)[cell viewWithTag:1];


        label.text=[NSString stringWithFormat:@"%@",text];
        [label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH          - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];
        [cell.contentView addSubview:label];
    }
return cell;
}
Risposto il 19/09/2012 a 10:30
fonte dall'utente

voti
8
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
{
    CGSize constraintSize = {245.0, 20000}
    CGSize neededSize = [ yourText sizeWithFont:[UIfont systemFontOfSize:14.0f] constrainedToSize:constraintSize  lineBreakMode:UILineBreakModeCharacterWrap]
if ( neededSize.height <= 18) 

   return 45
else return neededSize.height + 45 
//18 is the size of your text with the requested font (systemFontOfSize 14). if you change fonts you have a different number to use  
// 45 is what is required to have a nice cell as the neededSize.height is the "text"'s height only
//not the cell.

}
Risposto il 18/11/2012 a 17:20
fonte dall'utente

voti
5

Ho visto un sacco di soluzioni, ma tutto era sbagliato o uncomplet. È possibile risolvere tutti i problemi con 5 linee in viewDidLoad e autolayout. Questo per scopo principale C:

_tableView.delegate = self;
_tableView.dataSource = self;
self.tableView.estimatedRowHeight = 80;//the estimatedRowHeight but if is more this autoincremented with autolayout
self.tableView.rowHeight = UITableViewAutomaticDimension;
[self.tableView setNeedsLayout];
[self.tableView layoutIfNeeded];
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0) ;

Per SWIFT 2.0:

 self.tableView.estimatedRowHeight = 80
 self.tableView.rowHeight = UITableViewAutomaticDimension      
 self.tableView.setNeedsLayout()
 self.tableView.layoutIfNeeded()
 self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0)

Ora crea il tuo cellulare con XI ter o in Tableview nella Storyboard Con questo è alcuna necessità di implementare nulla di più o di ignorare. (Don dimenticare numero linee os 0) e l'etichetta inferiore (vincolare) downgrade "Content Abbracciare Priorità - Verticale di 250"

entrare descrizione dell'immagine qui entrare descrizione dell'immagine qui

Puoi scaricare il codice nel prossimo url: https://github.com/jposes22/exampleTableCellCustomHeight

Riferimenti: http://candycode.io/automatically-resizing-uitableviewcells-with-dynamic-text-height-using-auto-layout/

Risposto il 26/01/2016 a 19:58
fonte dall'utente

voti
5

Grazie a tutti i messaggi su questo argomento, ci sono alcuni modi davvero utile per regolare la rowHeight di un UITableViewCell.

Ecco una raccolta di alcuni dei concetti da tutti gli altri che in realtà aiuta quando si costruisce per iPhone e iPad. È inoltre possibile accedere a sezioni diverse e regolarle in base alle diverse dimensioni di punti di vista.

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

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
    int cellHeight = 0;

    if ([indexPath section] == 0) 
    {
        cellHeight = 16;
        settingsTable.rowHeight = cellHeight;
    }
    else if ([indexPath section] == 1)
    {
        cellHeight = 20;
        settingsTable.rowHeight = cellHeight;
    }

    return cellHeight;
}
else
{
    int cellHeight = 0;

    if ([indexPath section] == 0) 
    {
        cellHeight = 24;
        settingsTable.rowHeight = cellHeight;
    }
    else if ([indexPath section] == 1)
    {
        cellHeight = 40;
        settingsTable.rowHeight = cellHeight;
    }

    return cellHeight;
}
return 0;
} 
Risposto il 22/03/2012 a 21:02
fonte dall'utente

voti
3

Per avere l'altezza della cella dinamico come il testo di aumenti Label, è necessario prima di calcolare l'altezza, che il testo gonna uso nel -heightForRowAtIndexPathmetodo delegato e tornare con le altezze aggiunti di altre etichette, immagini (altezza massima di testo + altezza di altri statica componenets) e usare stessa altezza nella creazione di cellule.

#define FONT_SIZE 14.0f
#define CELL_CONTENT_WIDTH 300.0f  
#define CELL_CONTENT_MARGIN 10.0f

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

    if (indexPath.row == 2) {  // the cell you want to be dynamic

        NSString *text = dynamic text for your label;

        CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

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

        return height + (CELL_CONTENT_MARGIN * 2);
    }
    else {
        return 44; // return normal cell height
    }
}

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

    static NSString *CellIdentifier = @"Cell";

    UILabel *label;

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

    label = [[UILabel alloc] initWithFrame:CGRectMake(10, 5, 280, 34)];

    [label setNumberOfLines:2];

    label.backgroundColor = [UIColor clearColor];

    [label setFont:[UIFont systemFontOfSize:FONT_SIZE]];

    label.adjustsFontSizeToFitWidth = NO;

    [[cell contentView] addSubview:label];


    NSString *text = dynamic text fro your label;

    [label setText:text];

    if (indexPath.row == 2) {// the cell which needs to be dynamic 

        [label setNumberOfLines:0];

        CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);

        CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

        [label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), MAX(size.height, 44.0f))];

    }
    return  cell;
}
Risposto il 01/08/2012 a 12:07
fonte dall'utente

voti
2

Per impostare dimensione automatica per altezza di righe e altezza di righe stimato, assicurare seguenti operazioni per, autoquotatura efficace per il layout altezza della cella / riga.

  • Assegnare e implementare Tableview DataSource e delegare
  • Assegna UITableViewAutomaticDimensiona rowHeight & estimatedRowHeight
  • Implementare delegato / metodi dataSource (cioè heightForRowAte restituire un valore UITableViewAutomaticDimensionad essa)

-

Obiettivo C:

// in ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

  @property IBOutlet UITableView * table;

@end

// in ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    self.table.dataSource = self;
    self.table.delegate = self;

    self.table.rowHeight = UITableViewAutomaticDimension;
    self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}

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

    return UITableViewAutomaticDimension;
}

Swift:

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

    // Set automatic dimensions for row height
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension
}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Per esempio etichetta UITableViewCell

  • Impostare il numero di righe = 0 (e modalità di interruzione linea = troncare coda)
  • Impostare tutti i vincoli (in alto, in basso, a destra a sinistra) rispetto al suo contenitore superview / cell.
  • Opzionale : impostare l'altezza minima per l'etichetta, se si vuole area verticale minima coperta da etichetta, anche se non ci sono dati.

entrare descrizione dell'immagine qui

Nota : Se hai più di un etichette (UIElements) con lunghezza dinamica, che dovrebbe essere regolata in base alle sue dimensioni contenuti: Regolare 'Abbracciare Contenuto e compressione Resistenza priority` per le etichette che si desidera espandere / comprimere con priorità più alta.

Qui, in questo esempio ho impostato partire abbracciare e priorità elevata resistenza a compressione, che porta a calare più priorità / importanza per i contenuti in seconda etichetta (giallo).

entrare descrizione dell'immagine qui

Risposto il 02/02/2018 a 15:20
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more