После перемещения строки UITableView, а затем ее выбора, по краям она становится только синей - PullRequest
4 голосов
/ 19 февраля 2009

У меня есть UITableView с переупорядочиваемыми строками, и я использую стандартное свойство UITableViewCell.text для отображения текста. Когда я нажимаю «Изменить», перемещаю строку, нажимаю «Готово», затем нажимаю на строку, встроенный UILabel становится полностью белым (текст и фон) и непрозрачным, а синий оттенок ячейки за ним не отображается. Что дает? Есть ли что-то, что я должен делать, а я нет? У меня есть хакерское решение, но я хочу настоящего Маккоя.

Вот как это воспроизвести:

Начиная со стандартного шаблона «Навигационное приложение» в iPhone OS 2.2.1 SDK:

  1. Открыть RootViewController.m

  2. Раскомментируйте viewDidLoad и включите кнопку редактирования:

    - (void)viewDidLoad {
        [super viewDidLoad];
        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        self.navigationItem.rightBarButtonItem = self.editButtonItem;
    }
    
  3. Укажите, что таблица имеет несколько ячеек:

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 4;
    }
    
  4. В tableView:cellForRowAtIndexPath: добавьте строку для установки свойства текста ячейки и, следовательно, для использования встроенного подпредставления UILabel:

    // Set up the cell...
    cell.text = @"Test";
    
  5. Чтобы включить переупорядочение, раскомментируйте tableView:moveRowAtIndexPath:toIndexPath:. Реализация по умолчанию пуста, что хорошо в этом случае, так как шаблон не включает модель данных.

  6. Настройка проекта для симулятора, ОС 2.2.1, Build and Go. Когда приложение запустится, нажмите «Изменить», затем сдвиньте любую строку на новую позицию, нажмите «Готово», а затем нажмите каждую строку по одной за раз. Обычно касание выделяет строку, окрашивает ее в синий цвет и делает текст белым. Но при нажатии на строку, которую вы только что переместили, и оставляют цвет фона UILabel белым. В результате получается белое открытое пространство с синими полосами по краям. Как ни странно, после первого фальшивого касания появляется другое касание, чтобы исправить проблему.

Пока что я нашел хак, который это исправляет, но я не доволен этим. Он работает, гарантируя, что встроенный UILabel не будет непрозрачным и не будет иметь фонового цвета, сразу после выбора.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // hacky bugfix: when a row is reordered and then selected, the UILabel displays all crappy
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    for (UIView *view in cell.contentView.subviews) {
        if ([[view class] isSubclassOfClass:[UILabel class]]) {
            ((UILabel *) view).backgroundColor = nil;
            view.opaque = NO;
        }
    }

    // regular stuff: only flash the selection, don't leave it blue forever
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
}

Кажется, это работает, но я не ожидаю, что это будет хорошей идеей навсегда. Как правильно это исправить?

Ответы [ 4 ]

6 голосов
/ 26 февраля 2009

Это похоже на ошибку в рендеринге UITableView, и вы должны подать отчет об ошибке Radar. Как будто клетки не обновляются должным образом после переезда.

Один из способов обойти это сейчас - это не использовать встроенный ярлык, а свернуть свой в ячейке:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

        CGRect frame = cell.contentView.bounds;
        frame.origin.x = frame.origin.x + 10.0f;

        UILabel *textLabel = [[UILabel alloc] initWithFrame:frame];
        [textLabel setAutoresizingMask:UIViewAutoresizingFlexibleRightMargin];
        textLabel.tag = 1;
        textLabel.textAlignment = UITextAlignmentLeft;
        textLabel.backgroundColor = [UIColor clearColor];
        textLabel.textColor = [UIColor blackColor];
        textLabel.font = [UIFont boldSystemFontOfSize:20.0];
        textLabel.numberOfLines = 1;
        textLabel.highlightedTextColor = [UIColor whiteColor];
        [cell.contentView addSubview:textLabel];
        [textLabel release];

    }

    UILabel *textLabel = (UILabel *)[cell viewWithTag:1];
    textLabel.text = @"Test";

    return cell;
}

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

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

2 голосов
/ 06 апреля 2009

Трюк в решении от Брэда выглядит так:

textLabel.backgroundColor = [UIColor clearColor];

Если вы оставите фон по умолчанию, у вас все равно будет проблема, даже когда вы катите свои собственные ячейки UITableViewCells. Причина, по которой я оставил его по умолчанию, заключается в том, что в документации сказано, что использование непрозрачных фонов обходится дешевле в вычислительном отношении. В идеале я бы не хотел использовать [UIColor clearColor] для исправления этой ошибки.

Возможно, полностью окрашенная ячейка каким-то образом исправит это. Хотя я не пробовал их раньше.

У кого-нибудь еще есть решение для этого?

1 голос
/ 17 июня 2009

Спасибо за информацию, я искал, как стереть цвет фона с UILabel.

Я использовал следующую строку:

textLabel.backgroundColor = [UIColor clearColor];

и работал отлично !!!

спасибо

Алехандра:)

0 голосов
/ 27 февраля 2010

Выбор не предназначен для показа в течение длительных периодов! (Мы постучались по этому поводу для нескольких наших приложений)

??? Это означает, что Apple не одобрит свое собственное приложение Календарь на iPhone! Когда вы собираетесь редактировать время начала и окончания события, время начала выбирается бесконечно, оно изменяется только после того, как пользователь нажимает на следующее поле.

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