2013-07-04 70 views
0

即時獲取錯誤:*終止應用程序,由於未捕獲的異常'NSInternalInconsistencyException',原因:'嘗試將0行插入0節,但0節後只有0行更新'*在uitableview單元格中的自定義複選框出錯

我有2個部分,我試圖做到這一點,當你點擊其中一個部分的單元格的複選框時,它會轉到另一部分(例如:第1部分 - >第2部分)

這裏是我的一些相關的代碼:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"]; 
    if (!cell) 
     cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"]; 
    if([indexPath section] == 0){ 
    cell.textLabel.text = [[[taskArray objectAtIndex:[indexPath row]] taskName] uppercaseString]; 
    cell.imageView.image = [UIImage imageNamed:@"checkboxtry2.png"]; 
    } else if ([indexPath section] == 1) { 
    cell.textLabel.text = [[[completedArray objectAtIndex:[indexPath row]] taskName] uppercaseString]; 
    cell.imageView.image = [UIImage imageNamed:@"checkboxtry2selected.png"]; 
    } 

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handlechecking:)]; 
    [cell.imageView addGestureRecognizer:tap]; 
    cell.imageView.userInteractionEnabled = YES; 
    return cell; 
} 
-(void)handlechecking:(UITapGestureRecognizer *)t{ 
     CGPoint tapLocation = [t locationInView:self.tableView]; 
     NSIndexPath *tappedIndexPath = [self.tableView indexPathForRowAtPoint:tapLocation]; 

     if (tappedIndexPath.section == 0) { 
      [completedArray addObject:[taskArray objectAtIndex:tappedIndexPath.row]]; 
      [taskArray removeObject:[taskArray objectAtIndex:tappedIndexPath.row]]; 
     } 
     else { 
      [taskArray addObject:[completedArray objectAtIndex:tappedIndexPath.row]]; 
      [completedArray removeObject:[completedArray objectAtIndex:tappedIndexPath.row]]; 
     } 
     [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:tappedIndexPath] withRowAnimation: UITableViewRowAnimationFade]; 
} 

我有兩個數組:taskArray它處理在第0對象和completedArray負責處理在部分對象1.

---編輯--- 這是我現在有: TableViewController.h

@interface ToDoTableViewController : UITableViewController <Properties2ViewControllerDelegate, UITableViewDelegate, SettingsViewControllerDelegate> 
@property (strong, nonatomic) NSMutableArray *taskArray; 
@property (strong, nonatomic) NSMutableArray *completedArray; 
@property (strong, nonatomic) NSMutableArray *holdViewsArray; 
-(IBAction)addCell:(id)sender; 
-(void)buttonPressed:(id)sender; 
-(void)handlechecking:(UITapGestureRecognizer *)t; 

TableViewController.m

-(void) viewDidLoad{ 
    [self.tableView setDelegate:self]; 
    [self setModalTransitionStyle:UIModalTransitionStyleCrossDissolve]; 

    taskArray = [[NSMutableArray alloc] init]; 
    completedArray = [[NSMutableArray alloc]init]; 
    holdViewsArray = [[NSMutableArray alloc]init]; 
    } 
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"]; 
    if (!cell) 
     cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"]; 
    NSString *detailText = [NSString stringWithFormat:@"%.0f", [[taskArray objectAtIndex:[indexPath row]] timeInterval]]; 
    [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; 
    [cell setBackgroundColor:[UIColor colorWithRed:236.0/255 green:240.0/255 blue:241.0/255 alpha:1.0f]]; 
    cell.textLabel.textColor = baseColor; 
    [[cell detailTextLabel] setText:detailText]; 
    [[cell detailTextLabel] setFont:[UIFont fontWithName:@"Avenir-Black" size:12]]; 
    [[cell textLabel] setFont:[UIFont fontWithName:@"AvenirNext-DemiBold" size:16]]; 

    if([indexPath section] == 0){ 
    cell.textLabel.text = [[[taskArray objectAtIndex:[indexPath row]] taskName] uppercaseString]; 
    cell.imageView.image = [UIImage imageNamed:@"unchecked.png"]; 
    } else if ([indexPath section] == 1) { 
    cell.textLabel.text = [[[completedArray objectAtIndex:[indexPath row]] taskName] uppercaseString]; 
    cell.imageView.image = [UIImage imageNamed:@"checked.png"]; 
    } 

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handlechecking:)]; 
    [cell.imageView addGestureRecognizer:tap]; 
    cell.imageView.userInteractionEnabled = YES; 
    return cell; 

} 
-(void)handlechecking:(UITapGestureRecognizer *)t{ 

     CGPoint tapLocation = [t locationInView:self.tableView]; 
     NSIndexPath *tappedIndexPath = [self.tableView indexPathForRowAtPoint:tapLocation]; 
     NSIndexPath *newIndexPath = nil; 

     if (tappedIndexPath.section == 0) { 

      NSUInteger newRowIndex = self.completedArray.count; 
      [self.completedArray addObject:[self.taskArray objectAtIndex:tappedIndexPath.row]]; 
      [self.taskArray removeObject:[self.taskArray objectAtIndex:tappedIndexPath.row]]; 
      newIndexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:1]; 
     } else { 

      NSUInteger newRowIndex = self.taskArray.count; 
      [self.taskArray addObject:[self.completedArray objectAtIndex:tappedIndexPath.row]]; 
      [self.completedArray removeObject:[self.completedArray objectAtIndex:tappedIndexPath.row]]; 
      newIndexPath = [NSIndexPath indexPathForRow:newRowIndex inSection:0]; 
     } 
     [self.tableView beginUpdates]; 
     [self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone]; 
     [self.tableView deleteRowsAtIndexPaths:@[tappedIndexPath] withRowAnimation:UITableViewRowAnimationNone]; 
     [self.tableView endUpdates]; 
} 
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 
    NSInteger num = 0; 
    if (section == 0) { 
     num = self.taskArray.count; 
    } else { 
     num = self.completedArray.count; 
    } 
    return num; 
} 


-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{ 
    Tasks *taskToMove = [taskArray objectAtIndex:[sourceIndexPath row]]; 
    if (sourceIndexPath.row > destinationIndexPath.row) { 
     [taskArray insertObject:taskToMove atIndex:destinationIndexPath.row]; 
     [taskArray removeObjectAtIndex:(sourceIndexPath.row + 1)]; 
    } 
    else if (sourceIndexPath.row < destinationIndexPath.row) { 
     [taskArray insertObject:taskToMove atIndex:(destinationIndexPath.row + 1)]; 
     [taskArray removeObjectAtIndex:(sourceIndexPath.row)]; 
    } 
} 
-(IBAction)addCell:(id)sender{ 
    Properties2ViewController *pvc = [[Properties2ViewController alloc]init]; 
    [pvc setDelegate:self]; 
    [self presentViewController:pvc animated:YES completion:NULL]; 
    [pvc setModalTransitionStyle:UIModalTransitionStyleCrossDissolve]; 
} 
-(void)properties2ViewControllerDidEnterPropertiesSuccesfully:(Tasks *)t{ 
    if (![[t taskName] isEqual: @""]) { 
    [taskArray addObject:t]; 
    } 
    [self.tableView reloadData]; 
} 

Properties2ViewController.m

-(IBAction)dismiss:(id)sender{ 
    testTask = [[Tasks alloc]init]; 
    testTask.taskName = taskName.text; 
    testTask.timeInterval = datePicker.countDownDuration; 
    testTask.dateCreated = [NSDate date]; 
    if ([self.delegate respondsToSelector:@selector (properties2ViewControllerDidEnterPropertiesSuccesfully:)]){ 
     [self.delegate properties2ViewControllerDidEnterPropertiesSuccesfully:testTask]; 
    } 
    [self dismissViewControllerAnimated:YES completion:NULL]; 
} 

Properties2viewcontroller是一個模式控制器,它將Task對象添加到taskArray。

+0

嘗試重新加載整個表視圖,你改變一排以上時你將它從一個部分移動到另一個部分。 – Wain

+0

您可以爲此場景提供屏幕截圖。所以我可以幫你以你想要的方式 - –

+0

首先使用你的數組的屬性(例如self.taskArray,而不是taskArray)。通過這種方式,你的屬性的setter和getters將被自動調用,你可以避免一些可能的內存錯誤。爲數組添加惰性實例(例如 - (NSMutableArray *)taskArray {if(!_taskArray){_taskArray = [NSMutableArray array];} return _taskArray;})並將其從viewDidLoad中移除。設置特殊的斷點來查看應用程序崩潰的方法。 Post方法將數據添加到所有空陣列。 – Numeral

回答

1

您正在嘗試重新加載行,但你真正想要做的是從0段刪除的行並將其添加到第1節或反之亦然。因此,在handlechecking方法,你必須寫這樣的事:

-(void)handlechecking:(UITapGestureRecognizer *)t{ 

CGPoint tapLocation = [t locationInView:self.tableView]; 
NSIndexPath *tappedIndexPath = [self.tableView indexPathForRowAtPoint:tapLocation]; 
NSIndexPath *newIndexPath = nil; 

if (tappedIndexPath.section == 0) { 

    NSUInteger newRowIndex = self.sectionTwoArr.count; 
    [self.sectionTwoArr addObject:[self.sectionOneArr objectAtIndex:tappedIndexPath.row]]; 
    [self.sectionOneArr removeObject:[self.sectionOneArr objectAtIndex:tappedIndexPath.row]]; 
    newIndexPath = [NSIndexPath indexPathForRow:newRowindex inSection:1]; 
} else { 

    NSUInteger newRowIndex = self.sectionOneArr.count; 
    [self.sectionOneArr addObject:[self.sectionTwoArr objectAtIndex:tappedIndexPath.row]]; 
    [self.sectionTwoArr removeObject:[self.sectionTwoArr objectAtIndex:tappedIndexPath.row]]; 
    newIndexPath = [NSIndexPath indexPathForRow:newRowindex inSection:0]; 
} 
[self.tableView beginUpdates]; 
[self.tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationNone]; 
[self.tableView deleteRowsAtIndexPaths:@[tappedIndexPath] withRowAnimation:UITableViewRowAnimationNone]; 
[self.tableView endUpdates]; 
} 

編輯

全面實施的其他方法

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    self.sectionOneArr = [@[@"ololo", @"dsd", @"dsdfsf"] mutableCopy]; 
    self.sectionTwoArr = [@[@"ototo",@"dd", @"sdfsdfsd"] mutableCopy]; 
} 


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 

    return 2; 
} 


-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 

    NSInteger num = 0; 
    if (section == 0) { 
     num = self.sectionOneArr.count; 
    } else { 
     num = self.sectionTwoArr.count; 
    } 
    return num; 
} 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"]; 
    if (!cell) 
     cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"]; 
    if([indexPath section] == 0){ 
     cell.textLabel.text = [[self.sectionOneArr objectAtIndex:[indexPath row]] uppercaseString]; 
     cell.imageView.image = [UIImage imageNamed:@"unchecked.jpeg"]; 
    } else if ([indexPath section] == 1) { 
     cell.textLabel.text = [[self.sectionTwoArr objectAtIndex:[indexPath row]] uppercaseString]; 
     cell.imageView.image = [UIImage imageNamed:@"checked.jpeg"]; 
    } 

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(handlechecking:)]; 
    [cell.imageView addGestureRecognizer:tap]; 
    cell.imageView.userInteractionEnabled = YES; 

    return cell; 
} 


- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 

    NSString * num = nil; 
    if (section == 0) { 
     num = @"One"; 
    } else { 
     num = @"Two"; 
    } 
    return num; 
} 
+0

,不幸的是沒有工作。我得到一個錯誤:我收到終止應用程序錯誤*由於未捕獲的異常「NSRangeException」,原因是:「* - [__ NSArrayM objectAtIndex:]:索引0超越界限空陣」 – EvilAegis

+0

user2533646,我編輯我的答案,並測試它在測試項目上。它應該工作 – Numeral

+0

嗯它半工作。有時它的工作,但是當我邀請了幾位行我得到:終止應用程序由於未捕獲的異常「NSInternalInconsistencyException」,理由是:「無效的更新:在第0包含在後的現有部分的行數行數無效更新(0)必須更新(2)之前等於包含在該部分中的行的數目,加上或減去插入或從該部分(0插入時,1刪除)和加上或刪除的行的數量減去的數行移入或移出該部分(0移入,0移出)。' – EvilAegis

0

你的代碼看起來正確,但我會冒險猜測問題出在你的tableView:numberOfRowsInSection:方法中。你是否爲每個部分返回適當的行數?應該是這樣的:

if([indexPath section] == 0){ 
    return [taskArray count]; 
} else { 
    return [completeArray count]; 
} 
+0

是的,我實際上確實有:/ – EvilAegis