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…
2 Comentários
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!
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.