0

I am pretty new to IOS Programming and this will be my first app. I have a TableViewController to show the Data History (CoreData) and I am trying to implement a SearchBar (iOS8). Besides a minor issure with the layout it works fine (see Screenshot, the tableView does not have full width and there is this lupe...?, does anyone know why this is?) enter image description here

My bigger problem is that when I delete a row without using the searchbar it works, but when I am searching for an entry and try to delete, it deleted it but I get an exception and the view gets stuck with the red "Deletion"-Button. If I go back to the main view and back to the tableview the view is updated..

*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.93/UITableView.m:1582 2015-06-24 10:55:25.635 Pedal[9203:284856] CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)

Here's my code for the two methods I think are relevant (correct me if I am wrong)

- (void)tableView:(UITableView *)inTableView commitEditingStyle:(UITableViewCellEditingStyle)inStyle forRowAtIndexPath:(NSIndexPath *)inIndexPath {
if(inStyle == UITableViewCellEditingStyleDelete) {
    //[inTableView beginUpdates];

    RecordingInfo *theItem = [self entryAtIndexPath:inIndexPath]; 
    NSError *theError = nil;

    [self.managedObjectContext deleteObject:theItem];
    if([self.managedObjectContext save:&theError]) {

        if(self.searchController.active) {
            NSMutableArray *theResult = [self.searchResult mutableCopy];

            [theResult removeObjectAtIndex:inIndexPath.row];
            self.searchResult = theResult;
            [inTableView deleteRowsAtIndexPaths:@[inIndexPath]
                               withRowAnimation:UITableViewRowAnimationFade];
            NSLog(@"deletion successful");
        }
    }
    else {
        NSLog(@"Unresolved error while deleting %@", theError);
    }
    //[self.tableView endUpdates];
}   
}

is it possible I need to add a similar if-question in controller:didChangeObject:?

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {

UITableView *tableView = self.tableView;

switch(type) {

    case NSFetchedResultsChangeInsert:
        [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationRight];
        break;

    case NSFetchedResultsChangeDelete:
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
        break;

    case NSFetchedResultsChangeUpdate:
        [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
        break;

    case NSFetchedResultsChangeMove:
        [tableView deleteRowsAtIndexPaths:[NSArray
                                           arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [tableView insertRowsAtIndexPaths:[NSArray
                                           arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
        break;
}
}

If anyone can help I'd be very glad, I am trying to solve this forever now! Thanks!

Parth Bhatt
  • 19,381
  • 28
  • 133
  • 216
Kathiieee
  • 211
  • 1
  • 3
  • 10
  • do you have: func controllerWillChangeContent(controller: NSFetchedResultsController) { self.tableView.beginUpdates() } – Mikael Jun 24 '15 at 09:06
  • @Mikael yes I do, and I also have: controllerDidChangeContent:(NSFetchedResultsController *)controller { [self.tableView endUpdates]; } – Kathiieee Jun 24 '15 at 09:11
  • Also check your : func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { let sectionInfo = self.fetchedResultsController.sections![section] as! NSFetchedResultsSectionInfo return sectionInfo.numberOfObjects } – Mikael Jun 24 '15 at 09:15
  • I think that one should be right too: - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. if (self.searchController.active) { return [self.searchResult count]; } else { id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; return [sectionInfo numberOfObjects]; } } – Kathiieee Jun 24 '15 at 09:18
  • well, If I were you I would put a breakpoint here. This " if (self.searchController.active)" is suspicious and seems related to your issue. – Mikael Jun 24 '15 at 09:24
  • I was there before.. it throws the excpetion at the self.managedObjectContext save:&theError line but it continues and deletes the object (deletion successful) and if I switch views and come back, its gone. – Kathiieee Jun 24 '15 at 09:33
  • @Mikael if I try to delete with the search, it calls: ControllerdidChangeObject, and then it calls it again (?) and then breaks at the indexpath part and throws the exception – Kathiieee Jun 24 '15 at 09:43
  • can you put a breakpoint in : numberOfRowsInSection ? see if it returns the proper number of rows for your 2 different delete actions? – Mikael Jun 24 '15 at 10:41
  • @Mikael okay I tried that, when I have 3 objects and I delete it it says 3 objects before and after the deletion. without the searchbar it goes from 3 to 2 like it should.. – Kathiieee Jun 24 '15 at 11:15
  • ok, that's clearly a problem then cause it's not the expected result :) Can you give more details ? you have 2 tests to do : check the number of rows in section when you have the focus in the searchBar and check the number of rows in section when your searchController is NOT active. – Mikael Jun 24 '15 at 11:19
  • basically you can simply return id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; and remove your IF condition. that might do the trick here. but first, check if you get the right number of rows in both cases. – Mikael Jun 24 '15 at 11:20
  • numberOfRowsInSection gives back the correct numbr of rows in both cases.. it seems to only screw up when deleting, I guess when deleting it should not give back the count of the searchResult but the numberofobjects.. if I remove the if I can't even click the searchBar (Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array' ) – Kathiieee Jun 24 '15 at 11:34
  • yes, my bad. your code for the numberOfRowsInSection seems good. The problem is still the same though: in the case you have 3 objects in the list, you should get 2 objects after deletion when you have the searchBar active. – Mikael Jun 24 '15 at 11:50
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/81401/discussion-between-kathiieee-and-mikael). – Kathiieee Jun 24 '15 at 12:04

1 Answers1

0

You are using a single array for deleting object. You should check condition for deleting object. Does it is from search bar or normal. If it is from search bar then get that object and search it in main table view array and then delete it.

Rajesh Maurya
  • 3,026
  • 4
  • 19
  • 37
  • I figured, but how do I do that? Plus the object gets deleted, the view is just not updated (it's like the swiping just gets stuck) – Kathiieee Jun 24 '15 at 09:15
  • Please check out this answer. http://stackoverflow.com/questions/20790234/deleting-a-cell-in-search-bar-table-view-causes-delete-to-be-executed-twice – Rajesh Maurya Jun 24 '15 at 09:18
  • I checked it before, that's why I posted my controller:DidChangeObject: code but I have no idea how to ACTUALLY implement it.. – Kathiieee Jun 24 '15 at 09:21