TableView单元格自定义类型文本重叠本身或为空白 [英] TableView Cell Custom type Text Overlaps itself or is Blank

查看:109
本文介绍了TableView单元格自定义类型文本重叠本身或为空白的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

希望有人可以建议我使用自定义标签填充 UITableViewCell 的正确方法。我仍然遇到相同的问题,标签是空白或当表填充细胞重复使用的显示重叠标签文本。

Hoping someone can advise me on the correct method to populate a UITableViewCell with custom labels. I keep running into the same issues , either the label is blank or when the table fills up with cells reused ones show overlapping label text.

我已经按照他人的建议,但每一种方式我都会打破。

I have followed what has been advised for others here but each way I do it something breaks.

**更新**

我已将代码更改为以下内容,大部分工作除外,当我选择标签重叠的单元格时, 。我使用的教程的代码可以在这里找到: https://github.com/funkyboy/Core-Data-on-iOS-5-Tutorial--How-To-Work-with-Relations-and-Predicates

I have changed the code to below and have most of it working except when I select a cell the label overlaps as in the screenshot below. The code for the tutorial I am using can be found here: https://github.com/funkyboy/Core-Data-on-iOS-5-Tutorial--How-To-Work-with-Relations-and-Predicates

这里是我的代码:

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

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

FailedBankInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];

CGRect infoFrame = CGRectMake(10, 10, 200, 16);
UILabel *infoLabel = [[UILabel alloc] initWithFrame:infoFrame];
infoLabel.textColor = [UIColor blackColor];
infoLabel.backgroundColor = [UIColor yellowColor];
infoLabel.font = [UIFont systemFontOfSize:12];
infoLabel.textAlignment = NSTextAlignmentCenter;
infoLabel.tag = indexPath.row;
infoLabel.text = [NSString stringWithFormat:@"%@, %@", info.city, info.state];
[cell addSubview:infoLabel];

return cell;
}

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

FailedBankInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];
UILabel *theLabel = (UILabel *)[cell.contentView viewWithTag:indexPath.row];
theLabel.text = [NSString stringWithFormat:@"%@, %@",
                 info.city, info.state];

}


$ b <单元与Core Data和 fetchedresultcontroller if(!cell)我将标记更改为indexPath.row编号。如果你使用预定义的单元格类型,我遵循的每个教程都很好。如果我使用自定义与我自己的标签,它从来没有工作。我应该不使用fetchedresultscontroller为tableview数据?如果我在详细视图中更改城市标题并保存,则调用以下代码:

Because I am using the Prototype Cell with Core Data and fetchedresultcontroller the if(!cell) is never called. I changed the tag to be the indexPath.row number. Every tutorial I have followed works fine if you use the predefined cell types. If I use Custom with my own labels it never works out. Should I not use a fetchedresultscontroller for the tableview data? If I change the city title in the detail view and save it the following code gets called:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

UITableView *tableView = self.tableView;

switch(type) {

    case NSFetchedResultsChangeInsert:
        [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeDelete:
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeUpdate:
        [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
        break;

    case NSFetchedResultsChangeMove:
        [tableView deleteRowsAtIndexPaths:[NSArray
                                           arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [tableView insertRowsAtIndexPaths:[NSArray
                                           arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;
    }
}

以下是一些截图:

推荐答案

***更新 - 使用自定义单元格时,删除原型单元格,因为您不需要它!

***Update - When using custom cells remove the prototype cell as you don't need it!!

我终于明白了为什么它不工作。整个问题是Prototype Cell,因为你必须设置一个重用标识符,在大多数教程中,他们使用字符串Cell。

I finally figured out why it was not working. The whole problem is the Prototype Cell because you have to set a reuse Identifier and in most of the tutorials they use the string "Cell".

在其中具有标识符单元格的单元格,因此它不创建新单元格,它只是重新使用具有标识符单元格的单元格。

When the tableview load it already has a cell in it with the Identifier "Cell" so it doesn't create a new cell it just reuses the cell that has the Identifier "Cell".

static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

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

上述块if(cell == nil)重用已经存在的Prototype单元格。另一个问题是在这个块下面创建如下标签:

The above block if (cell == nil) is never called because it is reusing the Prototype cell that is already there. The other problem is creating the label below this block as in:

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

if (!cell) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
FailedBankInfo *info = [_fetchedResultsController objectAtIndex:indexPath.row];

CGRect infoFrame = CGRectMake(10, 10, 200, 16);
UILabel *infoLabel = [[UILabel alloc] initWithFrame:infoFrame];
infoLabel.textColor = [UIColor blackColor];
infoLabel.backgroundColor = [UIColor yellowColor];
infoLabel.font = [UIFont systemFontOfSize:12];
infoLabel.textAlignment = NSTextAlignmentCenter;
infoLabel.tag = 101;
infoLable.text = [NSString stringWithFormat:@"%@, %@",
         info.city, info.state];
[cell.contentView addSubview:infoLabel];

return cell;
}

这看起来工作正常,因为它创建标签,屏幕,你发现标签是重叠自己,因为在我的问题。这是因为当单元格离开屏幕并回来时,cellForRowAtIndexPath重用已经有一个标签并在顶部创建另一个标签的单元格。这种情况会持续发生,直到您在同一个单元上有7,8个或更多标签重叠。我通过在didSelectRowatIndex中放置一个NSlog来计算这里的子视图的数量,我这样做:

This appears to work fine as it does create the Label but when you scroll the screen you find that Labels are overlapping themselves as in my problem. This is because when a cell goes off screen and comes back on the cellForRowAtIndexPath reuses a cell that already has a label and creates another Label over the top. This keeps happening until you have 7, 8 or more Labels overlapping on the same cell. I worked this out by putting an NSlog in the didSelectRowatIndex to count the number of subviews here:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

NSLog(@"Count is:%i", [[tableView cellForRowAtIndexPath:indexPath].contentView.subviews count]);
}

所以你需要做的是在if == nil),并使用else来仅设置Label的文本。这个工作的关键是每个单元格必须有一个唯一的重复标识符,所以当CellforRowatIndexPath被调用时,它第一次出现时创建一个新的单元格。当该单元格离开屏幕并回到一个新的单元格不创建它只是重复使用现有的单元格,并更改文本,而不创建另一个标签。我已经检查这与另一个NSlog在if(cell == nil)它为每个单元格一次,之后它不会激发,因为它重用出列单元格。我只是使用一个字符串myCell+ indexPath.row的标识符。在故事板中,我仍然有原型单元格的单元格的标识符。它抱怨,如果你没有什么东西在那里。这里是我的最终代码:

So what you need to do is create the custom Label inside the if (cell == nil) and use an else to only set the text of the Label. The key for this to work is that each cell has to have a unique reuse Identifier so when CellforRowatIndexPath is called it creates a new cell the first time it appears. When that cell goes off screen and comes back on a new cell is not created it just reuses the existing one and changes the text without creating another Label. I have checked this with another NSlog in the if (cell == nil) it fires once for each cell and after that it doesn't fire because it reuses dequeued cells. I just used a string "myCell" + indexPath.row for the Identifier. In the storyboard I still have the Identifier of "Cell" for the Prototype cell. It complains if you don't have something in there. Here is my final code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *myCellID = [NSString stringWithFormat:@"myCell%i", indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:myCellID];

FailedBankInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:myCellID];
    CGRect infoFrame = CGRectMake(10, 10, 200, 16);
    UILabel *infoLabel = [[UILabel alloc] initWithFrame:infoFrame];
    infoLabel.textColor = [UIColor blackColor];
    infoLabel.backgroundColor = [UIColor yellowColor];
    infoLabel.font = [UIFont systemFontOfSize:12];
    infoLabel.textAlignment = NSTextAlignmentCenter;
    infoLabel.tag = 101;
    infoLabel.text = [NSString stringWithFormat:@"%@", info.name];
    [cell.contentView addSubview:infoLabel];
}
else {
    UILabel *theLabel = (UILabel *)[cell viewWithTag:101];
    theLabel.text = [NSString stringWithFormat:@"%@", info.name];
}

return cell;
}

我仍然在使用代码:

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

FailedBankInfo *info = [_fetchedResultsController objectAtIndexPath:indexPath];
UILabel *theLabel = (UILabel *)[cell viewWithTag:101];
theLabel.text = [NSString stringWithFormat:@"%@", info.name];
}

当Core数据对象使用以下代码更改时更新标签文本:

To update the label text when the Core data object changes with the following code:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

UITableView *tableView = self.tableView;

switch(type) {

    case NSFetchedResultsChangeInsert:
        [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeDelete:
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;

    case NSFetchedResultsChangeUpdate:
        [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
        break;

    case NSFetchedResultsChangeMove:
        [tableView deleteRowsAtIndexPaths:[NSArray
                                           arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [tableView insertRowsAtIndexPaths:[NSArray
                                           arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;
  }
}



我也发现有时当回到表视图该表并不总是更新,所以修复这个你可以使用:

I also found sometimes when segueing back to the table view the table doesn't always update so to fix this you can use:

-(void) viewWillAppear {
[self.tableView reloadData];
}

感谢您的所有输入,它帮助我找到一个解决方案希望这可以帮助任何人遇到同样的问题。我想我已经解释得够好了。我不是任何方式的专家。只是另一个试图建立一个应用程序的人:)

Thanks for all of your input it did help me come to a solution and I hope that this helps anyone else who is experiencing the same issue. I think I have explained it well enough. I'm not an expert by any means. Just another guy trying to build an App :)

这篇关于TableView单元格自定义类型文本重叠本身或为空白的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆