Как остановить ячейку UITableView, переписывая содержимое?

Я использую 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

Ответ 1

    // cell reuse
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

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

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

Ответ 2

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

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

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

Дайте ему свойство UILabel * cellLabel и сделайте весь код, который у вас выше, помимо установки текста меток в init 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 в построителе интерфейса.

Ответ 3

- (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, чтобы он работал правильно.

Ответ 4

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

Вы можете удалить любой 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;

Ответ 5

Введите этот код для коллекцииView. Это поможет удалить двуличность из ячейки многократного использования.

- (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;

}

Ответ 6

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

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

Ответ 7

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

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

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

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

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;