2012-10-13 17 views
5

Ho una sottoclasse UITableViewCell.Impossibile aggiornare il frame dell'oggetto UI in UITableViewCell

Ho bisogno di cambiare dinamicamente il frame di un UILabel.

Ecco che cosa ho fatto:

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

    cell.Content.Text = @"Content!"; 
    [cell.Content setFrame:CGRectMake(0, 0, 10, 10)]; 
} 

Il testo del UILabel non cambia quindi questo non è un problema IBOutlet. Il frame rimane lo stesso definito in IB.

ho fatto cose del genere prima, quindi non sono davvero sicuro di cosa è andato storto qui ...

Grazie per qualsiasi aiuto.

Edit:

Io uso

[self.tableView registerNib:[UINib nibWithNibName:@"MessageCell" bundle:nil] 
    forCellReuseIdentifier:@"MessageCell"]; 

in viewDidLoad

risposta

4

Beh un paio di giorni dopo la pubblicazione della grazia che ho trovato la risposta, spero che questo aiuterà qualcuno un giorno ...

io non sono sicuro al 100% perché, ma quello che ho cercato di fare semplicemente non può da fare:

Non è possibile modificare la cornice di un oggetto se lo si è inserito tramite Interface Builder.

Per apportare le modifiche che volevo fare, ho semplicemente creato quegli oggetti in modo programmatico nella mia sottoclasse, all'interno di "initWithCoder".

content = [[UILabel alloc] initWithFrame:CGRectMake(120, 100, 200, 50)]; 
content.opaque = NO; 
content.numberOfLines = 0; 
[self.contentView addSubview:content]; 

sono stato poi in grado di cambiare le cornici dentro "- (void) layoutSubviews" (ma in fondo da nessuna parte ho voluto)

- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 
    [cell.Content setFrame:CGRectMake(0, 0, 10, 10)]; 

    ... 
2

Ci deve essere qualcosa di sbagliato c'è.

prova, soloper il test per implementare questo:

tableView:willDisplayCell:forRowAtIndexPath: 

Come

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    MessageCell* aCell = (MessageCell*)cell; 
    aCell.Content.Text = @"Content!"; 
    [aCell.Content setFrame:CGRectMake(0, 0, 10, 10)]; 
} 

Qual è il risultato?

+0

rimane lo stesso sfortunato ... – BenB

+0

Great Daniel ha funzionato per me. Finalmente hai dato una soluzione ad un problema molto noto. –

1

Aggiungere una sottoview a cell.Content e ridimensionare quella sottoview anziché il contenuto stesso. La cella verrà sempre allungata per adattarsi alla vista tabella in modo da non renderla più piccola.
(e naturalmente per rendere l'altezza della cella più piccola basta applicare tableView:heightForRowAtIndexPath:)

+0

Non ho provato a modificare la vista della cella, ma un UILabel all'interno di quella cella. – BenB

1

Può essere che questo si riferisce al fatto di riutilizzare la cella. Prova questo

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     static NSString *CellIdentifier = @"messageCell"; 
     MessageCell *cell = (MessageCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 
    if(cell == nil) 
     { 
     cell = [[[MessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]autorelease]; 
     } 
     cell.Content.Text = @"Content!"; 
     [cell.Content setFrame:CGRectMake(0, 0, 10, 10)]; 
     return cell; 
    } 
+0

L'app non raggiunge mai (cell == nil) ... – BenB

+0

Hai impostato l'origine dati della tua vista tabella? Cosa intendi per app non raggiungendo (cell == nil), viene chiamato cellForRowAtIndexPath? – Animesh

+0

Intendevo dire che la cella non è mai nulla – BenB

1

Avete considerato l'override del metodo - (void) layoutSubviews nella tua cella personalizzato (vale a dire MessageCell) e il layout vostra roba lì? Penso che questo sia il posto più sicuro dove inserire il codice di modifica del layout, perché in altri punti potrebbe non avere alcun effetto. Non dimenticare di chiamare [super layoutSubviews]; nella tua implementazione di layoutSubviews.

Considerate di andare con questo approccio e fateci sapere se ha funzionato per voi! Ma è necessario considerare le implicazioni di prestazioni con questo approccio, perché layoutSubviews verrà chiamato ogni volta che la tabella scorre.

EDIT:

per ospitare per la dimensione giusta cornice per l'etichetta all'interno layoutSubviews considerare l'utilizzo - (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode per il calcolo telaio.

+0

Ancora non ottenendo alcun risultato ... Mi sono assicurato che venga chiamato il layout sottoposto a override in MessageCell, e ho anche chiamato la super funzione – BenB

+0

Un altro tentativo molto imbarazzante: scavalcare il metodo "- (void) setFrame: (CGRect) frame" nel tuo MessageCell.m (chiama super ancora una volta) e inserisci un'istruzione NSLog lì per vedere quando viene chiamata durante il ciclo di ridisegno della vista tabella! –

+0

E un'altra domanda riguardante la mia risposta iniziale: nel metodo "layoutSubviews" sottoposto a override, quando chiamate "[super layoutSubviews]"? Prova a mettere la chiamata su super DOPO aver impostato la cornice per la tua etichetta. –

2

Non puoi modificare cornice di oggetto dell'interfaccia utente creata attraverso xib se Autolayout è acceso Ci sono due modi per fare ciò:

  1. Disabilitare l'Autolayout per quel xib.

O

  1. Fai IBOutlet per particolare vincolo NSlayout allegarlo conseguenza e aggiornare il valore della proprietà costante tramite il codice e non dimenticare di chiamare layOutIfNeeded adeguatamente sull'oggetto su quale constarint è implementato o superview in base all'implementazione.
Problemi correlati