UILabel Align on Top

29thJul 10

Ontem durante mais uma noitada de volta do Cocoa, descobri uma coisa que me parece algo absurda.

Precisei de utilizar uma UILabel para conter uma string, mas à partida nunca sei o tamanho da string… e quero que a string esteja sempre alinhada no topo da UILabel, tenha ela uma ou várias linhas. No entanto – e de forma algo bizarra – isto é impossível de fazer com um simples atributo do objecto.

Então houve necessidade de recorrer um pouco ao engenho e ficou algo deste tipo:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   static NSString *CellIdentifier = @"FollowingCell";
   UILabel *myLabel;
 
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
 
   if (cell == nil)
   {
      cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
      cell.contentView.backgroundColor = [UIColor whiteColor];
      myLabel = [[[UILabel alloc] initWithFrame:CGRectMake(54.0f, 20.0f, 220.0f, 90.0f)] autorelease];
      myLabel.font = [UIFont systemFontOfSize:13.0];
      myLabel.tag = MY_TAG;
      myLabel.textColor = [UIColor blackColor];
      myLabel.lineBreakMode = UILineBreakModeWordWrap;
      myLabel.numberOfLines = 10;
      [cell.contentView addSubview:myLabel];
   } else {
      myLabel = (UILabel *)[cell.contentView viewWithTag:MY_TAG];
   }
 
   myLabel.text = myDataSource.myText;
   CGRect myLabelRect = [myLabel textRectForBounds:myLabel.bounds limitedToNumberOfLines:999];
   CGRect newHeight = myLabel.frame;
   newHeight.size.height = myLabelRect.size.height;
   myLabel.frame = newHeight;
 
   return cell;
}

Talvez tenham necessidade de implementar também este próximo método para que a altura da célula se adapte à quantidade de texto existente:

- (CGFloat) tableView: (UITableView *) tableView heightForRowAtIndexPath: (NSIndexPath *) indexPath
{
   MyDataSource *myDataSource = [fetchedResultsController objectAtIndexPath:indexPath];
 
   NSString *text = myDataSource.myText;
   CGFloat height = [text sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(220,200) lineBreakMode:UILineBreakModeWordWrap].height;
 
   return height+25;
}

E desta forma tenho uma UILabel em cada célula da tabela que independentemente da quantidade de texto que contém, adapta-se em altura de forma a “acomodá-lo” e colocar sempre o texto alinhado no topo.

Esta solução não é inteiramente da minha autoria. Encontrei já nem sei onde um “pedaço” de código para alinhar em baixo para uma dada quantidade de linhas, e aproveitei para modificá-lo e adaptar às minhas necessidades.

Espero que seja útil para mais alguém…

Esta entrada foi publicada em Código, iOS Dev e com as tags , , , . Guardar nos favoritos o link permanente. Publicar comentário ou deixar um trackback: URL de Trackback.

2 Comentários

  1. Publicado 29 de Julho de 2010 às 12:49 | Link

    Olá Bruno,

    Também tive esse problema, e a solução que acabei por encontrar foi exactamente a mesma.

    No entanto, mais tarde vim a usar a biblioteca Three20 e a StyledTextLabel deles tem o comportamento por defeito de alinhar verticalmente acima. Não será a solução se não se usar nada mais dessa biblioteca, mas é no entanto bom saber q o problema está resolvido algures.

    Continuação de bons posts!

    • Publicado 29 de Julho de 2010 às 14:28 | Link

      Viva João,

      Por acaso também encontrei a solução da Three20, mas como em princípio não iria utilizar mais funções… acabei por adaptar esta, evitando estar a incluir mais uma biblioteca no projecto.
      :)

Publicar Comentário

O seu endereço de e-mail nunca será publicado ou partilhado. Campos obrigatórios marcados com *

*
*

Pode usar as seguintes tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">