Поведение UILabel Text при выборе Custom UITableViewCell: текст смешивается или накладывается на ранее загруженную метку - PullRequest
1 голос
/ 29 ноября 2010

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

В любом случае, вот оно:

У меня есть UITableView, для которого я отображаю пользовательский встроенный UITableViewCell, вот где я их создаю:

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

    NSDictionary *myDictionary = [myArray objectAtIndex:indexPath.row];

    UITableViewCell *cell = [tableView
                 dequeueReusableCellWithIdentifier:CellIdentifier];  

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


    CGRect textViewRect = CGRectMake(10.0, 0.0, 250, 25);
    UILabel *textView = [[UILabel alloc] initWithFrame:textViewRect];

    textView.text = [myDictionary objectForKey:@"name"];
    textView.font = [UIFont systemFontOfSize:12.0];
    textView.textColor = [UIColor blackColor];
    textView.highlightedTextColor = [UIColor whiteColor];
    textView.textAlignment = UITextAlignmentRight;

    [cell.contentView addSubview:textView];
    [textView release];


    CGRect imageRect = CGRectMake(270.0, 15, 16, 16);
    UIImageView *icon = [[UIImageView alloc] initWithFrame:imageRect];

    icon.image = [myDictionary objectForKey:@"color-icon"];
    icon.highlightedImage = [myDictionary objectForKey:@"gray-icon"];

    [cell.contentView addSubview:icon];
    [icon release];
}

Итак, как вы можете видеть, довольно стандартные вещи ... Затем, когда я нажимаю на одну из ячеек, вместо таблицы загружается другое представление. До сих пор все хорошо, но потом, когда я возвращаюсь к этому табличному представлению и что оно должно перезагрузить, проблема начинается ...

Кстати, я добавил это в методы делегата, чтобы ячейки никогда не оставались выделенными:

- (void)tableView:(UITableView *)tableView
                 didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    // [...] a lot more code here 
}

Когда я щелкаю мышью по своей ячейке в симуляторе и держу ее нажатой, ячейка остается выбранной как и ожидалось (так же, как и на самом устройстве), и вот почему я получаю:

[Изображение 1]

Текст UILabel полностью перепутан! Снимок экрана - это последняя ячейка таблицы, а перекрывающийся текст - первая ячейка. И поведение на первом аналогично, если я продолжу щелкать по нему, оно покажет то же поведение, смешиваясь с текстом UILabel последней ячейки. Я предполагаю, что это связано с тем, как работает dequeueReusableCellWithIdentifier (вероятно, очередь FILA).

Конечно, я попытался обойти это и нашел некоторые действительно странные вещи.

Если я не нажимаю на ячейки идеально, никаких ошибок, правильный текст отображается и т. Д .:

[Изображение 2]

Затем я попытался немного испортить параметры моей UILabel. Я добавил это:

textView.backgroundColor = [UIColor clearColor];

И когда я делаю это, как только таблица перезагружается, мне даже не нужно выделять ячейку, чтобы увидеть поведение завинчивания:

[Изображение 3]

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

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

было заменено на:

UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero 
                               reuseIdentifier: CellIdentifier] autorelease];

Но, конечно, это не будет работать в долгосрочной перспективе из-за утечки памяти ...

Также следует отметить, что у меня точно такое же поведение для другого UITableView в другом представлении где-то в этом приложении ... Другая пользовательская ячейка более сложная, больше меток, больше изображений и т. Д., Но все метки демонстрируют такое же поведение. И это более сложное табличное представление управляется контроллером навигации, поэтому нет никакой пользовательской загрузки / выгрузки, как первый ...

Это все, что у меня есть, и я не могу найти решение ... пожалуйста, помогите!

Аааа, это действительно раздражает ... Я новичок, поэтому не могу публиковать изображения ... :( Вот ссылка, где вы можете увидеть ссылки на изображения: https://skitch.com/aponsin/rne9k/fullscreen.png-100-layer-3-rgb-8

Alex

1 Ответ

0 голосов
/ 29 ноября 2010

Проблема в том, что вы создаете новую метку и добавляете ее в ячейку каждый раз, когда ячейка используется повторно.Чтобы исправить это, вы должны создать ярлык только при создании ячейки:

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

    CGRect textViewRect = CGRectMake(10.0, 0.0, 250, 25);
    UILabel *textView = [[UILabel alloc] initWithFrame:textViewRect];
    textView.tag = kLabelTag;
    textView.font = [UIFont systemFontOfSize:12.0];
    textView.textColor = [UIColor blackColor];
    textView.highlightedTextColor = [UIColor whiteColor];
    textView.textAlignment = UITextAlignmentRight;

    [cell.contentView addSubview:textView];
    [textView release];


    CGRect imageRect = CGRectMake(270.0, 15, 16, 16);
    UIImageView *icon = [[UIImageView alloc] initWithFrame:imageRect];

    icon.image = [myDictionary objectForKey:@"color-icon"];
    icon.highlightedImage = [myDictionary objectForKey:@"gray-icon"];

    [cell.contentView addSubview:icon];
    [icon release];
}

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

UILabel *textView = (UILabel*)[cell.contentView viewWithTag:kLabelTag];
textView.text = [myDictionary objectForKey:@"name"];

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

Также взгляните на компоненты, которые стандарт UITableViewCell уже предоставляет (в зависимости от стиля ячейки) - там уже есть UIImageView и UILabels, и вы можетеустановите для них свои собственные свойства и используйте их без создания дополнительных компонентов

...