Как остановить, чтобы ячейка UITableView перезаписывала содержимое? - PullRequest
11 голосов
/ 21 марта 2012

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

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

Мне требуется UILabel вручную, потому что позже мне понадобятся пользовательские ячейки.

По мере того, как я прокручиваю вверх и вниз, метки становятся все ярче и смелее; они всегда перекрывают друг друга, а иногда даже влияют на строки, расположенные ниже (даже до того, как они появятся в области просмотра).

Если я продолжу это делать, содержимое клетки станет непонятным.

Это происходит, только если там backgroundColor не установлен как clearColor.

Я пытался [cellLabel setClearsContextBeforeDrawing:YES]; и [self.tableView setClearsContextBeforeDrawing:YES]; безрезультатно.

Если я использую cell.textLabel.text, проблема, похоже, исчезнет.

Ниже приведен код и пример изображения.

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

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

        // Configure the cell...
        //[self configureCell:cell atIndexPath:indexPath];


        NSString *txt = @"Product";


        //cell.textLabel.text = txt;
        cell.selectionStyle = UITableViewCellSelectionStyleNone;

        UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, cell.frame.size.height)];

        UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
        [cellLabel setText:txt];
        [cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
        [cellLabel setBackgroundColor:[UIColor clearColor]];

        [cellView addSubview:cellLabel];
        [cellLabel release];
        [cell.contentView addSubview:cellView];
        [cellView release];


        return cell;
    }


Image follows;


![image of uitableview][1]


  [1]: http://i.stack.imgur.com/5lNy6.png


// Edit to include context

I am using a dictionary to display the contents of the UITableViewCells.

I have attempted to do the following;

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

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

            [self configureCell:cell atIndexPath:indexPath];
        } // end if


        // Configure the cell...
        //
       // Moved to inside the cell==nil        

        return cell;
    }

-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{

    // Get the txt from the Dictionary/Plist... *removed due verboseness*

    UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
    [cellLabel setText:txt];
    [cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
    [cellLabel setBackgroundColor:[UIColor clearColor]];

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

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

Смотри картинку ниже;

repeating labels in uitableview

Ответы [ 7 ]

17 голосов
/ 21 марта 2012
    // cell reuse
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

   if (cell == nil) { //cell initialization

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

6 голосов
/ 03 января 2013

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

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

@interfacce MyCustomCell : UITableViewCell
    @property (nonatomic) UILabel *cellLabel;
@end

. Присвойте ему свойство UILabel * cellLabel и сделайте весь код, который у вас есть, кроме установки текста меток в инициализации MyCustomCell.m, замените все экземпляры.ячейки с собственной личностью, например:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

    if (self)
    {
        self.cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
        [self.cellLabel setText:txt];
        [self.cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
        [self.cellLabel setBackgroundColor:[UIColor clearColor]];
    }

    return self;
}

Теперь в вашем cellForRowAtIndexPath используйте MyCustomCell, где вы проверяете, имеет ли ячейка == nil, вы также можете проверить метку ячейки:

if(cell == nil || cell.cellLabel == nil)

Инициализируйте его точно так же:

cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

сейчас все, что вам нужно сделать, это установить:

cell.cellLabel.text = ....;

ваш код в cellForRowAtIndexPath намного чище, эффективнее с точки зрения памяти ии вы не получите свою ошибку.

Не забудьте установить в ячейке вашего типа тип MyCustomCell в конструкторе интерфейсов.

4 голосов
/ 25 июня 2014

Это немного более старая тема.Но кому-то будет полезно,

. Вы можете удалить любые view, добавленные к cell, прежде чем то же самое будет повторно использовано в tableView.

. Этот код сделает это,

for (UIView* view in [cell.contentView subviews])
{
    if ([view isKindOfClass:[UILabel class]])  //Condition if that view belongs to any specific class       
    {
        [view removeFromSuperview];
    }
}

Это можно добавить перед настройкой ячейки,

if (!cell) {
    cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier];

} 

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

cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;
cell.textLabel.font = nil;
4 голосов
/ 13 августа 2012
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 

           UITableViewCell *cell = (UITableViewCell*)[self.YourTableName dequeueReusableCellWithIdentifier:nil];        
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
        }


            return cell; 
        }

используйте ReusablecellIdentifier nil, чтобы он работал правильно .....

2 голосов
/ 09 декабря 2015

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

- (void)viewDidLoad {
[super viewDidLoad];
arrImg=[[NSMutableArray alloc]initWithObjects:@"images.jpeg",@"images-2.jpeg",@"images-3.jpeg", nil];

UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(375, 200)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];

[self.colView setCollectionViewLayout:flowLayout];
self.colView.backgroundColor=[UIColor lightGrayColor];
self.colView.delegate=self;
self.colView.dataSource=self;

// Do any additional setup after loading the view, typically from a nib.
 }

  -(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {


CollectionViewCell1 *cell=(CollectionViewCell1 *)[colView dequeueReusableCellWithReuseIdentifier:@"CollectionViewCell1" forIndexPath:indexPath];
float xAxis=0;
float maxwidth=0;


for (UIView* view in [cell.contentView subviews])
{
    if ([view isKindOfClass:[UIScrollView class]])  //Condition if that view belongs to any specific class
    {
        [view removeFromSuperview];
    }
}
if(indexPath.row==1)
{
    UIScrollView *scroll=[[UIScrollView alloc]initWithFrame:CGRectMake(0,0, colView.frame.size.width, 200)];

    scroll.delegate = self;
    [cell.contentView addSubview:scroll];

    for(int i=0;i<[arrImg count];i++)
    {

    UIImageView *img=[[UIImageView alloc]init];
    xAxis=xAxis+maxwidth;
    img.frame=CGRectMake(xAxis, 0, self.view.frame.size.width, 200);
    img.image=[UIImage imageNamed:[NSString stringWithFormat:@"%@",[arrImg objectAtIndex:i]]];
        [scroll addSubview:img];
        maxwidth=self.view.frame.size.width;
    }

   scroll.contentSize=CGSizeMake(375*3, 200);
   scroll.pagingEnabled=YES;


}
   return cell;

}
0 голосов
/ 21 марта 2012

Ответ A-Live был лучшим решением.

Я нашел https://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html, чтобы привести более широкий пример.

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

Код, который я использовал ниже, может быть полезен, но пока он работает;

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

    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    UILabel *cellLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 120, 35)];
    [cellLabel setFont:[UIFont boldSystemFontOfSize:12]];
    [cellLabel setBackgroundColor:[UIColor clearColor]];
    [cellLabel setTag:1];
    [cell.contentView addSubview:cellLabel];
    [cellLabel release];




    // TextInput setup    
    CGRect cellTextFrame = CGRectMake(200, 12, 65, 30);


    UITextField *txtInputField = [[UITextField alloc] initWithFrame:cellTextFrame];
    [txtInputField setTag:2];
    [txtInputField setDelegate:self];
    [txtInputField setClearButtonMode:UITextFieldViewModeWhileEditing];
    [txtInputField setContentVerticalAlignment:UIControlContentVerticalAlignmentCenter];
    [txtInputField setFont:[UIFont systemFontOfSize:12]];
    [txtInputField setReturnKeyType:UIReturnKeyDone];
    [txtInputField setTextAlignment:UITextAlignmentLeft];
    [txtInputField setKeyboardAppearance:UIKeyboardAppearanceDefault];
    [txtInputField setKeyboardType:UIKeyboardTypeNumbersAndPunctuation];
    [txtInputField setAutocorrectionType:UITextAutocorrectionTypeNo];
    [txtInputField setAutocapitalizationType:UITextAutocapitalizationTypeNone];
    txtInputField.clearButtonMode = UITextFieldViewModeWhileEditing;
    [txtInputField setBorderStyle:UITextBorderStyleRoundedRect];
    txtInputField.textColor = [UIColor colorWithRed:56.0f/255.0f green:84.0f/255.0f blue:135.0f/255.0f alpha:1.0f];
    //[txtInputField addTarget:self action:@selector(textFieldFinished:) forControlEvents:UIControlEventEditingDidEndOnExit];     

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

} // end if


// Configure the cell...
//
//[self configureCell:cell atIndexPath:indexPath];


UILabel *label = (UILabel *)[cell viewWithTag:1];
[label setText:txt];

UITextField *txtField = (UITextField *) [cell viewWithTag:2];
[txtField setText:txtText];
[txtField setPlaceholder:txtPlaceholder];



return cell;
0 голосов
/ 21 марта 2012

Старайтесь не помещать UIView * cellView поверх ячейки UITableViewCell *. UITableViewCell является подклассом UIView, поэтому вы можете добавить подпредставления, если хотите. Однако UITableViewCell уже имеет метку внутри.

Просто используйте [cell.textLabel setText:txt].

...