2013-02-28 3 views
1

Я подклассифицировал UITableViewCell. В основном, что происходит, когда вы нажимаете рисунок UITableViewCell на уровне ячейки, заставляя ячейку выглядеть иначе. Однако, когда я удаляю ячейку, этот рисунок падает на ячейку ниже. Это для меня, кажется, указывает на то, что формат ячейки снова используется, как это было бы нормально. Таким образом, я перерисовал ячейку в CellForRowAtIndexPath, как можно увидеть ниже ...UITableViewCell формат, повторно используемый после удаления

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"Cell"; 
AGProgressViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 
cell.textLabel.backgroundColor = [UIColor clearColor]; 
cell.detailTextLabel.backgroundColor = [UIColor clearColor]; 
//NSLog(@"progress value = %f", [cell.progress floatValue]); 

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

Task * task = nil; 

if (indexPath.section == 0){ 
    task = [self.tasksByDay[@"anyday"] objectAtIndex:indexPath.row]; 
} else if (indexPath.section == 1){ 
    task = [self.tasksByDay[@"monday"] objectAtIndex:indexPath.row]; 
} else if (indexPath.section == 2){ 
    task = [self.tasksByDay[@"tuesday"] objectAtIndex:indexPath.row]; 
} else if (indexPath.section == 3){ 
    task = [self.tasksByDay[@"wednesday"] objectAtIndex:indexPath.row]; 
} else if (indexPath.section == 4){ 
    task = [self.tasksByDay[@"thursday"] objectAtIndex:indexPath.row]; 
} else if (indexPath.section == 5){ 
    task = [self.tasksByDay[@"friday"] objectAtIndex:indexPath.row]; 
} else if (indexPath.section == 6){ 
    task = [self.tasksByDay[@"saturday"] objectAtIndex:indexPath.row]; 
} else if (indexPath.section == 7){ 
    task = [self.tasksByDay[@"sunday"] objectAtIndex:indexPath.row]; 
} 
cell.progress = [NSNumber numberWithFloat:([task.timeSpent floatValue]/[task.time floatValue])]; 
// this is calling the redrawing method in the cell 
[cell drawFillInAtPercent:[task.timeSpent floatValue]/[task.time floatValue]]; 

//NSLog(@"progress value = %f vs. time spent = %f", [cell.progress floatValue], [task.timeSpent floatValue]/[task.time floatValue]); 

cell.textLabel.text = task.name; 
cell.detailTextLabel.text = [NSString stringWithFormat:@"%d minutes", 
          [task.time intValue] - [task.timeSpent intValue]]; 

return cell; 
} 

Однако это не решило проблему. Все эти NSLogs показали, что ячейка находится на правильном уровне для каждого повторного рисования. Это означает, что по какой-то причине ячейка, которая удаляется, не получает вызов в пути cellForRowAtIndex. Странно, что текстовые метки меняются, просто пользовательский чертеж, который я делаю в подклассе UITableViewCell, не меняется.

Это метод, который я называю там в подклассе.

-(void) drawFillInAtPercent: (float) percent{ 
//if (percent > 0){ 
    NSLog(@"progress layer at percent %f", percent); 
    _progressLayer = [CAGradientLayer layer]; 
    _progressLayer.frame = CGRectMake(self.bounds.origin.x, 
             self.bounds.origin.y, 
             self.bounds.size.width * percent, 
             self.bounds.size.height); 
    _progressLayer.colors = @[(id)[[UIColor colorWithRed:0/255.0 green:0/250.0 blue:250.0/255.0 alpha:1.0f] CGColor], 
    (id)[[UIColor colorWithRed:150.0/200.0 green:150.0/200.0 blue:150.0/200.0 alpha:.5] CGColor], 
    (id)[[UIColor colorWithRed:200.0/200.0 green:200.0/200.0 blue:200.0/200.0 alpha:.5] CGColor], 
    (id)[[UIColor colorWithWhite:0.3f alpha:0.1f] CGColor]]; 
    _progressLayer.locations = @[@0.00f, @0.2f, @0.90f, @1.00f]; 
    [self.layer insertSublayer:_progressLayer atIndex:1]; 
//} 
} 

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

Эти методы удаления:

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (editingStyle == UITableViewCellEditingStyleDelete) { 

    [self deactivateTimers]; 
    NSArray * days = [NSArray arrayWithObjects: @"anyday", @"monday", @"tuesday",  @"wednesday", @"thursday", @"friday", @"saturday", @"sunday", nil]; 

    Task * task = self.tasksByDay[days[indexPath.section]][indexPath.row]; 

    if ([task.weekly boolValue]){ 
     task.finished = [NSNumber numberWithBool:1]; 
    } else { 
     [managedObjectContext deleteObject:task]; 
    } 

    [self.managedObjectContext save:nil]; 

    [self grabTasksFromContext]; 

    } 

} 

-(void) grabTasksFromContext{ 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    NSEntityDescription *entity = [NSEntityDescription 
           entityForName:@"Task" 
    inManagedObjectContext:managedObjectContext]; 
    [fetchRequest setEntity:entity]; 
    NSError *error; 
    NSMutableArray * managedObjects = [NSMutableArray arrayWithArray:[managedObjectContext 
    executeFetchRequest:fetchRequest error:&error]]; 
    int numObjects = [managedObjects count]; 

    for (int i = 0; i < numObjects; i ++){ 
     Task * task = [managedObjects objectAtIndex:i]; 
     NSLog(@"name %@", task.name); 
    // if the task is finished we don't want it to be displayed in the list 
     if ([task.finished boolValue]){ 
      NSLog(@"finished"); 
      [managedObjects removeObject:task]; 
      i -= 1; 
      numObjects -= 1; 
     } 
    } 

    self.tasks = managedObjects; 

// This implementation is pretty ugly 
// I'm sorry about that and will fix it in the future 
// probably the more attractive way to do this is to make an array of the days, and then    cycle through that and check through the array of tasks 
monday = tuesday = wednesday = thursday = friday = saturday = sunday = anyday = 0; 

NSMutableArray * mondayArray = [[NSMutableArray alloc] init]; 
NSMutableArray * tuesdayArray = [[NSMutableArray alloc] init]; 
NSMutableArray * wednesdayArray = [[NSMutableArray alloc] init]; 
NSMutableArray * thursdayArray = [[NSMutableArray alloc] init]; 
NSMutableArray * fridayArray = [[NSMutableArray alloc] init]; 
NSMutableArray * saturdayArray = [[NSMutableArray alloc] init]; 
NSMutableArray * sundayArray = [[NSMutableArray alloc] init]; 
NSMutableArray * anydayArray = [[NSMutableArray alloc] init]; 

for (Task * task in self.tasks){ 
    if ([task.day isEqualToString:@"monday"]){ 
     mondayArray[monday] = task; 
     monday++; 
    } else if ([task.day isEqualToString:@"tuesday"]){ 
     tuesdayArray[tuesday] = task; 
     tuesday++; 
    } else if ([task.day isEqualToString:@"wednesday"]){ 
     wednesdayArray[wednesday] = task; 
     wednesday++; 
    } else if ([task.day isEqualToString:@"thursday"]){ 
     thursdayArray[thursday] = task; 
     thursday++; 
    } else if ([task.day isEqualToString:@"friday"]){ 
     fridayArray[friday] = task; 
     friday++; 
    } else if ([task.day isEqualToString:@"saturday"]){ 
     saturdayArray[saturday] = task; 
     saturday++; 
    } else if ([task.day isEqualToString:@"sunday"]){ 
     sundayArray[sunday] = task; 
     sunday++; 
    } else { 
     anydayArray[anyday] = task; 
     anyday++; 
    } 
} 

    self.tasksByDay = [[NSDictionary alloc] initWithObjectsAndKeys: mondayArray,@"monday",  
    tuesdayArray, @"tuesday", wednesdayArray, @"wednesday", thursdayArray, @"thursday", 
    fridayArray, @"friday", saturdayArray, @"saturday", sundayArray, @"sunday", 
    anydayArray, @"anyday", nil]; 

    [self.tableView reloadData]; 
} 

Любая помощь или мысли о том, что происходит будут оценены.

ответ

2

Однако, когда я удаляю ячейку, этот чертеж падает в ячейку под ней.

Это важное замечание: это указывает мне, что в то время перерисовки происходит, модель (т.е. ваш self.tasksByDay[dayName]) имеет не был еще обновлен. Когда ячейка в определенной строке удаляется, taskByDay для соответствующего дня необходимо обновить, чтобы удалить соответствующую строку из NSArray. Если этого не произойдет, данные для удаленной задачи повлияют на рисование ячейки при следующем индексе, таким образом, визуальные wold кажутся «капли» одной строкой. Из вашего описания это звучит так, как будто это именно то, что происходит.

Вам необходимо убедиться, что к моменту обновления таблицы (или уведомление о удалении ячейки отправлено на UITableView) модель уже обновлена, чтобы не удалить строку. Таким образом, визуальные таблицы будут обновляться, как вы ожидаете.

Не напрямую связана с проблемой, но если вы создаете массив

NSArray *dayName = @[@"anyday", @"monday", @"tuesday", @"wednesday", etc.]; 

вы можете заменить длинную цепь if с с

task = [self.tasksByDay[dayName objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; 

Другая проблема в вашем коде является то, что каждый время, которое вы вызываете drawFillInAtPercent:, добавляется новый CAGradientLayer. Когда вы прокручиваете вверх и вниз, повторно используемые ячейки накапливают новые слои, не избавляясь от ранее добавленных. Вам нужно изменить свой код, чтобы добавить слой градиента только один раз, а затем повторно использовать существующий внутри вашего метода drawFillInAtPercent:. Например, вы можете добавить слой в назначенный инициализатор AGProgressViewCell, назначив его переменной экземпляра _progressLayer и добавив его в иерархию уровней один раз. С этого момента drawFillInAtPercent: изменит существующий _progressLayer, вместо того, чтобы создавать новые каждый раз.

+0

Хм это смущает меня, потому что я думал, что я изменил модель перед перезагрузкой таблицы ... в деле удаления я изменяю объект в контексте, сохраняю контекст, а затем вызываю метод, который я написал [self grabTasksFromContext] который сбрасывает модель и заканчивается [self.tableview reloadData] после сброса модели. Я не понимаю, как представление будет перерисовываться до того, как задача будет изменена в модели. – AdamG

+0

@AdamG Возможно, вам захочется обновить свой вопрос с помощью метода удаления, потому что ключом к проблеме может быть три. – dasblinkenlight

+0

Огромное вам спасибо за вашу помощь, и я обязательно сделаю это изменение, чтобы сделать мой код более удобочитаемым. Я добавил код удаления. – AdamG

Смежные вопросы