繁体   English   中英

使用正确的数据绘制自定义UITableCells

[英]Drawing custom UITableCells with the correct data

我有一个带有自定义表格单元的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
- (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的子类,则可以覆盖

-(无效)prepareForReuse

在单元返回之前被调用

-(UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)标识符

-(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字符串中设置一个Unique CellIdentifier,这会使较旧的单元出队。 这样,它免于填充重复的单元格。 希望您觉得合适并且符合您的喜好。 干杯!

也许表视图正在重用您的单元格,并通过重用当前设置的单元格为您提供随机结果; 您是否研究过UITableViewCell类的- (void)prepareForReuse

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM