UITableView имеет "уродливое" фоновое изображение для строк динамической высоты - PullRequest
0 голосов
/ 18 января 2010

Я создал UITableViewController, который вычисляет высоту для каждой строки в зависимости от объема текста, который она содержит. Код для расчета высоты строки выглядит следующим образом:

- (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
    Message *message = [[[[SessionData sharedSessionData] sessions] objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];
    CGSize size = [[message text] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    return size.height + (CELL_CONTENT_MARGIN * 2) + 38;
}

Как вы могли заметить, я использую отдельный класс в качестве UITableViewDatasource под названием SessionData. Внутри класса SessionData я рисую строки. Каждая строка имеет верхнее изображение, центральное изображение (которое повторяется в зависимости от высоты строки) и нижнее изображение. Моя проблема заключается в следующем: центральное изображение рисуется немного темнее, чем нижнее и верхнее изображения. Я предполагаю, что это как-то связано с повторяющейся природой изображения, так как верхнее и нижнее изображения хорошо прорисованы. Следующий код является частью моего сообщения [tableView: cellForRowAtIndexPath:]:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // other stuff here, most likely not related to my issue ...

    Message *message  = [[sessions objectAtIndex:[indexPath section]] objectAtIndex:[indexPath row]];       
    CGSize constraint = CGSizeMake(CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), 20000.0f);
    CGSize size = [[message text] sizeWithFont:[UIFont systemFontOfSize:FONT_SIZE] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];

    [label setText:[message text]];
    [label setFrame:CGRectMake(CELL_CONTENT_MARGIN, CELL_CONTENT_MARGIN - 5.0f, CELL_CONTENT_WIDTH - (CELL_CONTENT_MARGIN * 2), size.height)];
    [label setBackgroundColor:[UIColor clearColor]];

    viewTop = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"im1 top.png"]];
    viewMid = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"im1 mid.png"]];
    viewBot = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"im1 bot.png"]];      

    [viewTop setFrame:CGRectMake(0.0, 0.0, 300.0, 17.0)];
    [viewMid setFrame:CGRectMake(0.0, 17.0, 300.0, size.height - 10)];
    [viewBot setFrame:CGRectMake(0.0, 17.0 + size.height - 10, 300.0, 31.0)];

    [viewTop setBackgroundColor:[UIColor clearColor]];
    [viewMid setBackgroundColor:[UIColor clearColor]];
    [viewBot setBackgroundColor:[UIColor clearColor]];  

    [cell.backgroundView setBackgroundColor:[UIColor clearColor]];

    [((UIImageView *)cell.backgroundView) addSubview:viewTop];  
    [((UIImageView *)cell.backgroundView) addSubview:viewMid];  
    [((UIImageView *)cell.backgroundView) addSubview:viewBot];

    [[cell backgroundView] addSubview:label];   

    return cell;
}

Полагаю, мне нужно создать контейнерный вид с общим размером (ширина, высота) для верхнего, центрального и нижнего изображений и добавить контейнерный вид в ячейку, но это не сработало У кого-нибудь есть идеи, как решить эту проблему?

ОБРАТИТЕ ВНИМАНИЕ: Мой UITableViewController имеет градиент в качестве фонового изображения. Поэтому верхние / центральные / нижние изображения рисуются поверх градиента фона. Возможно, это тоже часть проблемы.

Ответы [ 2 ]

1 голос
/ 18 января 2010

Несколько вещей, на которые стоит обратить внимание.

Во-первых, в ваших ячейках происходит много обработки, что приводит к очень низкой производительности прокрутки на устройстве. Вы должны лучше использовать очереди ячеек и выполнять большинство настроек ячеек, общих для всех ячеек:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
        // Do cell layout in here!
    }

Таким образом, ячейки и их подпредставления могут повторно использоваться вместо воссоздания каждый раз, когда ячейка появляется на экране (используйте свойства tag и viewWithTag: методы представлений).

Во-вторых, вы можете посмотреть растягиваемые изображения .

В-третьих, вы заметите гораздо лучшую производительность, вручную рисуя ячейки. Создайте пользовательское представление (которое вы добавляете в представление содержимого), переопределите drawRect:, нарисуйте изображения на них, используя UIImage drawInRect: метод. Это значительно ускорит процесс! Нарисуйте все, что вы можете, потому что выкладка подвид стоит дорого! Также убедитесь, что вы не используете прозрачность UIView (в том числе UIImageView, UILabel и т. Д.), Если это возможно, установите opaque = YES и установите цвета фона. Желательно рисовать текст в drawRect:, используя NSString метод drawInRect:, который придаст вид прозрачного UILabel.

Однако, если у вас ОЧЕНЬ мало ячеек, например, <4 или что-то еще, возможно, метод рисования слишком велик. Тем не менее, это все еще очень рекомендуется! </p>

Надеюсь, это поможет!

0 голосов
/ 18 января 2010

Спасибо за ваши предложения Майкл. Я действительно мог бы исправить свои графические проблемы, используя следующий код:

[bubbleView setImage:[bubble stretchableImageWithLeftCapWidth:165 topCapHeight:30]];

Вместо того, чтобы использовать 3 отдельных изображения для создания пузырей чата, я могу теперь использовать 1 изображение, и оно растягивается изящно. Действительно очень хорошее предложение:)

Несмотря на то, что у меня не было особых проблем со скоростью, я частично переписал свой код, как вы и предлагали, главным образом путем создания основной части ячеек в части кода инициализатора ячеек. Я заметил небольшое улучшение скорости, возможно, это более заметно на устройстве (по сравнению с симулятором).

В настоящее время я все еще рисую свои изображения, используя ImageView (как вы могли заметить), я буду смотреть на [UIImage drawInRect:] всякий раз, когда мне потребуется более высокая скорость рендеринга.

Спасибо за ваши предложения, высоко ценится.

...