Рисование пользовательских ячеек, которые появляются при прокрутке - PullRequest
0 голосов
/ 04 февраля 2010

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

Все работает отлично и модно, кроме одной вещи, и я не могу понять, как ее решить. UITableView получает свои данные из массива проанализированных элементов XML, затем эти данные передаются в CustomCell моим RootViewController с использованием cellForRowAtIndexPath. Каждый CustomCell UITableView, который отображается, отображается правильно, однако, когда я прокручиваю вниз, я вижу дублирующиеся записи, которые только изменяются на правильный заголовок ячейки, когда выбран.

Таким образом, из 15 записей таблицы только 9 или 10 имеют правильные данные, когда изображение отображается, а 5 или 6, которые находятся вне поля зрения, показывают только правильные данные при выборе. Кто-нибудь может сказать, что я делаю неправильно или чего мне здесь не хватает? Спасибо!

RootViewController.h:

#import <UIKit/UIKit.h>

@interface RootViewController : UITableViewController {
    MyAppDelegate *appDelegate;
  UIToolbar *toolbar;
  NSArray *tableDataArray;
}

@property (nonatomic, retain) NSArray *tableDataArray;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil tableDataSource:(NSArray*)tableData;

@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

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

Обновление Я думаю, что я нашел корень проблемы. В старой ситуации, используя медленный процесс рисования, все ячейки были заранее утоплены и имели индекс. Теперь отображаются только те клетки, которые видны (первые восемь), а новые создаются на лету, когда они появляются (и получают соответствующий порядковый номер).

Я не уверен, что делать дальше. Есть ли способ подачи данных в новые ячейки, как только они будут созданы?

Ответы [ 2 ]

1 голос
/ 20 февраля 2010

Единственная вещь, которая сразу же вскочила на меня, была следующая строка:

cell = [[[CustomCell alloc] initWithFrame:CGRectZero reuseIdentifier:CustomCellIdentifier] retain];

Вы создаете здесь утечку памяти, и это может объяснить, почему старое содержимое ячеек сохраняется.

Попробуйте изменить его на:

cell = [[[CustomCell alloc] initWithStyle:UITableViewStylePlain reuseIdentifier:CellIdentifier]autorelease];
0 голосов
/ 14 июля 2010

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

- (void)setCellImage:(NSString *)s
{
cellImage = [s copy];
[self setNeedsDisplay]; 
}

В противном случае новые переменные не обновляются.

Надеюсь, это поможет.

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