我有一个带有自定义tablecells的UITableView。首先,我有一个版本,它实现了一个单独的NIB文件来创建自定义单元格视图,但这使得滚动非常慢。官方的答案是做自己的绘图,所以我实现了一个绘图变体(ABTableViewCell)。
现在一切正常,除了绘制视图外的单元格。前8个单元格被正确绘制 - 它们获得正确的标题,图像等 - 但除此之外的所有内容都会随机重复已绘制的单元格。只有在单击/触摸单元格时,才会使用正确的数据更新单元格的标签和图像。
我的RootViewController实现了UITableViewDataSource,并在那里初始化了CustomCell。
我已经验证所有数据都正确传递给CustomCell,因此它必须与绘图有关。我想我已经跟踪了这样一个事实:drawContentView
方法仅针对视图中的单元格而不是滚动到视图中的单元格。
如何再次触发drawContentView来更新进入视图的单元格?这是我必须从我的RootViewController做的事情,使用的不是:(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
?
CustomCell.h:
#import "ABTableViewCell.h"
@interface CustomCell : ABTableViewCell {
NSString * cellSubText;
NSString * cellText;
NSString * cellImage;
NSString * cellIcon;
NSString * cellId;
}
@property (nonatomic, copy) NSString *cellSubText;
@property (nonatomic, copy) NSString *cellText;
@property (nonatomic, copy) NSString *cellImage;
@property (nonatomic, copy) NSString *cellIcon;
@property (nonatomic, copy) NSString *cellId;
@end
CustomCell.m:
#import "CustomCell.h"
@implementation CustomCell
@synthesize cellSubText, cellText, cellImage, cellIcon, cellId;
static UIFont *celSubFont = nil;
static UIFont *cellFont = nil;
+ (void)initialize {
if(self == [CustomCell class]) {
cellSubFont = [[UIFont systemFontOfSize:13] retain];
cellFont = [[UIFont boldSystemFontOfSize:17] retain];
}
}
- (void)setFirstText:(NSString *)s {
[cellSubText release];
cellSubText = [s copy];
[self setNeedsDisplay];
}
- (void)setLastText:(NSString *)s {
[cellText release];
cellText = [s copy];
[self setNeedsDisplay];
}
- (void)drawContentView:(CGRect)r {
CGContextRef context = UIGraphicsGetCurrentContext();
UIColor *backgroundColour = [UIColor whiteColor];
UIColor *categoryColour = [UIColor grayColor];
UIColor *titleColour = [UIColor blackColor];
if(self.highlighted || self.selected) {
backgroundColour = [UIColor clearColor];
categoryColour = [UIColor whiteColor];
titleColour = [UIColor whiteColor];
}
[backgroundColour set];
CGContextFillRect(context, r);
CGPoint pCategory;
pCategory.x = 60;
pCategory.y = 3;
[categoryColour set];
[cellSubText drawAtPoint:pCategory forWidth:235 withFont:categoryFont minFontSize:13 actualFontSize:NULL lineBreakMode:UILineBreakModeTailTruncation baselineAdjustment:UIBaselineAdjustmentNone];
CGPoint pTitle;
pTitle.x = 60;
pTitle.y = 17;
[titleColour set];
[cellText drawAtPoint:pTitle forWidth:235 withFont:titleFont minFontSize:17 actualFontSize:NULL lineBreakMode:UILineBreakModeTailTruncation baselineAdjustment:UIBaselineAdjustmentNone];
//Display the image
CGPoint pImage;
pImage.x = 5;
pImage.y = 5;
NSData *imageData = [[NSData dataWithContentsOfURL:[NSURL URLWithString:cellImage]] retain];
UIImage *image = [UIImage imageWithData:imageData];
[image drawAtPoint:pImage];
}
- (void)dealloc {
[cellSubText release];
[cellText release];
[cellIcon release];
[cellImage release];
[super dealloc];
}
@end
RootViewController.m
#import "CustomCell.h"
#import "MyAppDelegate.h"
#import "RootViewController.h"
#import "DetailViewController.h"
@implementation RootViewController
@synthesize tableDataArray;
- (void)viewDidLoad {
[super viewDidLoad];
}
//Override the default initWithNibName method
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil tableDataSource:(NSArray*)tableData {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Custom initialization
tableDataArray = [tableData retain];
}
return self;
}
-(void)viewWillAppear:(BOOL)animated {
appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[super viewWillAppear:animated];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.tableDataArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCellIdentifier = @"CustomCellIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
if(cell == nil) {
cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CustomCellIdentifier] retain];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
NSUInteger row = [indexPath row];
NSDictionary *rowData = [self.tableDataArray objectAtIndex:row];
cell.cellSubText = [rowData objectForKey:@"Date"];
cell.cellText = [rowData objectForKey:@"Name"];
cell.cellImage = [rowData objectForKey:@"Image"];
cell.cellId = [rowData objectForKey:@"Id"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *selectedCell = [tableDataArray objectAtIndex:indexPath.row];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailView" bundle:[NSBundle mainBundle]];
detailViewController.selectedCell = selectedCell;
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
detailViewController = nil;
}
- (void)dealloc {
[super dealloc];
}
@end
答案 0 :(得分:2)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCellIdentifier = @"CustomCellIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CustomCellIdentifier];
if(cell == nil) {
cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CustomCellIdentifier] retain];
}
静态NSString * CustomCellIdentifier = @“CustomCellIdentifier”;
以上粗体代码正在为您做出这样的行为。
在iphone中,tableview重用已经创建的单元格。这是不可见的。 例如:前8个单元格将单独创建。当你向下滚动时,前几行将被隐藏。现在隐藏的细胞将被现在要显示的细胞重复使用。这就是为什么你会得到这种行为:)如果表视图内容较少,请尝试给出唯一标识符。
或
如果您的单元格是UITableViewCell的子类,则可以覆盖
- (void)prepareForReuse
在从
返回单元格之前调用- (UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)标识符
答案 1 :(得分:1)
表格视图可能会重复使用您的单元格,并通过重复使用当前设置的单元格为您提供随机结果;你看过- (void)prepareForReuse
班的UITableViewCell
吗?
答案 2 :(得分:1)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int myButtonTag = 1000+(10*indexPath.section)+indexPath.row;
NSString *kCellID = [NSString stringWithFormat:@"cellId_%i",myButtonTag];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellID];
if (cell == nil)
{
//[[cell viewWithTag:myButtonTag] removeFromSuperview];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID];
}
cell.accessoryType = UITableViewCellAccessoryNone;
}
为了在UITableView中快速滚动(特别是在ARC控制的环境中)时从单元格中删除数据,请记住在cellId字符串中设置唯一的CellIdentifier,这会使旧单元格出列。这样它就可以免于填充重复的细胞。希望您觉得合适并符合您的喜好。干杯!