Выравнивание меток в UITableViewCell - PullRequest
20 голосов
/ 15 июля 2009

Я использую UITableView с ячейками, созданными с использованием UITableViewCellStyleSubtitle . Высота каждой ячейки динамически регулируется с помощью

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

метод делегата.

Проблема, которую вы видите на картинке

( примечание: изображение обновлено )

http://img.skitch.com/20090715-g7srxgee2d7fhi5rab2wufrdgm.png

Как настроить выравнивание textLabel и detailTextLabel по верху ячейки? (Я действительно не хочу делать это путем создания подкласса UITableViewCell и переопределения layoutSubviews)

Thanx

Ответы [ 4 ]

36 голосов
/ 16 июля 2009

Ну, это стоило мне дня, но, думаю, я понял это. Насколько я могу судить, это похоже на ошибку в том, как UITableViewCell размещает textLabel и detailTextLabel. Когда вы устанавливаете высоту строки, кажется, что она выделяет одинаковую высоту для двух меток, что означает, что вы получаете именно то поведение, которое видите выше, даже если detailTextLabel требует больше места. Вот две вещи, которые я сделал, чтобы решить проблему. Мне пришлось создать подкласс UITableViewCell, чтобы исправить это, но это минимальный объем кода.

Сначала убедитесь, что вы правильно рассчитываете высоту каждого ряда. Поместите этот метод в ваш делегат табличного представления. Замените методы шрифта своими собственными:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
   NSString *cellDetailText = [[self itemForIndexPath: indexPath] detailDescription];
   NSString *cellText = [[self itemForIndexPath: indexPath] description];
   // The width subtracted from the tableView frame depends on:
   // 40.0 for detail accessory
   // Width of icon image
   // Editing width
   // I don't think you can count on the cell being properly laid out here, so you've
   // got to hard code it based on the state of the table.
   CGSize constraintSize = CGSizeMake(tableView.frame.size.width - 40.0 - 50.0, CGFLOAT_MAX);
   CGSize labelSize = [cellText sizeWithFont: [self cellTextLabelFont] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
   CGSize detailSize = [cellDetailText sizeWithFont: [self cellDetailTextLabelFont] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

   CGFloat result = MAX(44.0, labelSize.height + detailSize.height + 12.0); 
   return result;
}

Затем создайте подкласс UITableViewCell и переопределите layoutSubviews:

#import "UITableViewCellFixed.h"


@implementation UITableViewCellFixed
- (void) layoutSubviews {
   [super layoutSubviews];
   self.textLabel.frame = CGRectMake(self.textLabel.frame.origin.x, 
                                      4.0, 
                                      self.textLabel.frame.size.width, 
                                      self.textLabel.frame.size.height);
   self.detailTextLabel.frame = CGRectMake(self.detailTextLabel.frame.origin.x, 
                                           8.0 + self.textLabel.frame.size.height, 
                                           self.detailTextLabel.frame.size.width, 
                                           self.detailTextLabel.frame.size.height);
}
@end
8 голосов
/ 12 ноября 2010

Вот еще одно решение без подклассов ячеек, поэтому оно, безусловно, работает с различными стилями таблиц. (Я не проверял другие решения.) Строки заголовка и сведений объявлены в моем заголовке UITableViewController и уже определены. Они не очень длинные, конечно, на высоте 4000!

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

    CGRect frame = [UIScreen mainScreen].bounds;
    CGFloat width = frame.size.width;

    int section = indexPath.section;
    int row = indexPath.row;

    NSString *title_string = [title_strings_array objectAtIndex:row];
    NSString *detail_string = [detail_strings_array objectAtIndex:row];

    CGSize title_size = {0, 0};
    CGSize detail_size = {0, 0};

    if (title_string && [title_string isEqualToString:@""] == NO ) {
        title_size = [title_string sizeWithFont:[UIFont systemFontOfSize:22.0]
                              constrainedToSize:CGSizeMake(width, 4000)
                                  lineBreakMode:UILineBreakModeWordWrap];
    }

    if (detail_string && [title_string isEqualToString:@""] == NO ) {
        detail_size = [detail_string sizeWithFont:[UIFont systemFontOfSize:18.0]
                                constrainedToSize:CGSizeMake(width, 4000)
                                    lineBreakMode:UILineBreakModeWordWrap];
    }

    CGFloat title_height = title_size.height;
    CGFloat detail_height = detail_size.height;

    CGFloat content_size = title_height + detail_height;

    CGFloat height;

    switch ( section ) {

        case 0:
            height = content_size;
            break;

        //Just in case  
        default:
            height = 44.0;
            break;

    }

    return height;

}
1 голос
/ 15 июля 2009

Как бы вы ни измеряли ваши ячейки, вы должны делать это с помощью различных методов определения размера NSString. Таким образом, вы можете точно определить, какова высота ячейки и избежать пробелов.

0 голосов
/ 16 июля 2009

Если окажется, что textLabel и detailTextLabel размечены с использованием масок автоматического изменения размера, возможно, вы можете сделать это, когда вернете ячейку:

cell.textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin;
cell.detailTextLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

Если это работает, это немного проще, чем создавать подклассы в ячейке. Я еще не пробовал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...