代码之家  ›  专栏  ›  技术社区  ›  mensch

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

  •  0
  • mensch  · 技术社区  · 15 年前

    我有一个带有自定义表格单元格的UITableView。首先,我有一个版本,它实现了一个单独的NIB文件来创建自定义单元格视图,但是这使得滚动速度非常慢。官方的答案是绘制自己的图形,所以我实现了一个图形变量( ABTableViewCell )

    除了绘制不在视图中的单元格外,所有内容都在工作。前8个单元格的绘制是正确的——它们得到了正确的标题、图像等——但除此之外的所有内容都随机重复了已经绘制的单元格。只有单击/触摸单元格时,才会使用正确的数据更新单元格的标签和图像。

    我的rootViewController实现了UITableViewDataSource,并且在那里初始化了CustomCell。

    我已经验证了所有数据都正确地传递给了customcell,因此它必须与绘图有关。我想我已经追踪到 drawContentView 方法只对视图中的单元格调用,而不对滚动到视图中的单元格调用。

    如何再次触发drawContentView以更新进入视图的单元格?这是我必须从rootviewcontroller执行的操作,使用的不是: (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath ?

    客户单元:

    #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
    

    自定义单元格.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
    

    根视图控制器.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
    
    3 回复  |  直到 9 年前
        1
  •  2
  •   Manjunath    15 年前
    - (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];
        }
    

    static nsstring*customcellidentifier=@“customcellidentifier”;

    上面加粗的代码正在为您做出这样的行为。

    在iPhone中,TableView重用已经创建的单元格。不可见。 例:前8个单元格将单独创建。当你向下滚动时,前几行会被隐藏。现在隐藏的单元格将被现在要显示的单元格重用。这就是为什么您得到这种行为的原因:)如果表视图内容较少,请尝试给出唯一标识符。

    如果单元格是UITableViewCell的子类,则可以重写

    -(无效)重新使用前的准备

    在单元格返回之前调用

    -(UITableViewCell*)DequeueRusableCellWithIdentifier:(nsString*)标识符

        2
  •  1
  •   drewh    15 年前

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

        3
  •  1
  •   Mohsin Khubaib Ahmed    9 年前
    -(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中快速滚动时(尤其是在受弧控制的环境中)从单元格中删除数据,请记住在CellID字符串中设置唯一的CellIdentifier,它使旧单元格出列。这样就可以避免它填充重复的单元格。希望你觉得它合适并且符合你的喜好。干杯!