2012-03-20 6 views
11

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

+0

Возможный дубликат [UITableView повторяющихся ячеек на прокрутке] (http: // stackoverflow.com/questions/6844156/uitableview-repeating-cells-on-scroll) –

ответ

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

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

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

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

+0

Я пробовал настраивать UILabels под элементом 'cell == nil', в то время как это останавливает перезапись, это вызывает еще одну проблему - она ​​ставит данные в случайных областях в таблице. Мой фактический полный код использует словарь (plist), и ячейка начинает помещать ту же запись в случайные места по всей таблице, я обновлю свой вопрос, чтобы осветить эту проблему. – zardon

+2

@zardon UILabels, добавляемый один раз, не очищается при повторном использовании ячейки с помощью 'dequeueReusableCellWithIdentifier', это ваша ответственность за обновление содержимого subviews или сброс его внешнего вида по умолчанию (например, setText: @" для UILabel). В противном случае предварительно настроенные субвью будут отображаться в повторно используемых ячейках (в случае, если вы меняете контент ячейки условно). –

+0

Я попытался обновить контекст, но я не думаю, что он работает. Я попробую сделать UILabels init внутри ячейки == nil и попытаться получить к ним доступ по тегу и посмотреть, поможет ли это. Я мог бы найти учебники по этому поводу, так как раньше я этого не видел. – zardon

0

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

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

+0

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

-1

Ответ 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; 
4
- (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 ноль, так что работает правильно .....

+0

nice one thank – Chlebta

+0

Это единственное, что действительно сработало для меня .. – durazno

+0

Я пробовал xcode 7 ReusablecellIdentifier nil не работает. его show some null передал сообщение о недопустимом аргументе cellsee non argument. –

6

Вы добавляете метку к одной и той же повторно использовать ячейки каждый раз, поэтому она становится смелее. Когда вы используете 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, где вы проверить, если ячейка == ноль, вы можете также проверить этикетку ячейки:

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

Инициализировать его точно таким же образом:

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

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

cell.cellLabel.text = ....; 

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

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

+0

В нем говорится: «Я» неизменен в быстром? – mythicalcoder

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

Этот код для коллекции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; 

}