I am using this code... But it has terminated my application a few times:
- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
//FeedArray is NSMutableArray
if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.tableView beginUpdates];
[FeedArray removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
}
[self.tableView endUpdates];
}
Why is this happening? Is there any other way of doing this?
I think that [self.tableView endUpdates]; must be in if{} block
or [self.tableView beginUpdates]; must be before if{}
I used code like this, and it worked fine:
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self.tableView beginUpdates];
//Remove the item from the array (i.e. update the data source).
[self.arrayList removeObjectAtIndex:indexPath.row];
//Delete the row from the table.
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
}
Related
I want to stop all the rows being deleted from my table view by user so at least one row is always present.
Im still geting to grips with programming and objective c.
Heres what I tried:
if (indexPath.section != 0 | editingStyle == UITableViewCellEditingStyleDelete) {
[self.managedObjectContext deleteObject:[self.circuits objectAtIndex:indexPath.row]];
[self.appDelegate saveContext];
[self.circuits removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
then
if (indexPath.section > 1 | editingStyle == UITableViewCellEditingStyleDelete) {
[self.managedObjectContext deleteObject:[self.circuits objectAtIndex:indexPath.row]];
[self.appDelegate saveContext];
[self.circuits removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
That had no effect in that I can still delete the first row. So then I tried
- (BOOL)tableView:(UITableView *)commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == 0)
return NO;
return YES;
}
Still cant prevent the first row from being deleted
You need to implement the UITableViewDataSource method tableView:canEditRowAtIndexPath: and return NO for the indexPath.row 0.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return indexPath.row > 0;
}
Try moving your code into
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
Try this code :-
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0)
return NO;
else
return YES;
}
It will surely help you
In one of my ViewControllers, I added a tableview as a subview.
In this tableView I made implemented custom table view cells.
So, how to delete the custom Table View Cell from tableView, when we press the delete button.
Can anyone help me out..
Try this,
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[tableView beginUpdates];
[self.itemTable removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
I am having a big issue trying to delete from an UITableView.
Just for note, I have the same code running fine on another view and thats why it's making me crazy.
The only difference is that on the other view, my array is in a property. But I tried changing my tmpArray to a property and nothing changed. Here's the code and the error after:
-(void)tableView:(UITableView*)tableView willBeginEditingRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tmpArray removeObjectAtIndex:indexPath.row];
[tbvPlaylist deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
Error:
*** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1912.3/UITableView.m:1046
Let me now if you need more info.
Is tmpArray the same ivar that is providing the count of rows e.g.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return tmpArray.count;
}
Also at the moment you call
[tbvPlaylist deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
tableView:numberOfRowsInSection: should return the
numberOfRowsBeforeDelete - numberOfRowsBeingDeleted
So I am using an NSFetchedResultController to display data in my table.
I am getting an update notification, and both index and newIndex are set. So what do these two indexes represent during an update? and Why Am i getting values for both on an update notification?
Isn't newIndex for move notification only?
When i try to acces object at index [24, 4] I get a crash, because apparently an object doesn't exist at this indexPath. any idea what's going on here?
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[_tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
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;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex
forChangeType:(NSFetchedResultsChangeType)type
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[_tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[_tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)configureCell:(MyCustomCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
// Crashes on the line below, before calling setBook
Book *book = [_fetchedResultController objectAtIndexPath:indexPath];
[cell setBook:book];
}
Result during an update, right before my crash:
indexPath [24, 4]
newIndexePath [32, 4]
I've the following question in Objective-C. When I delete an object from my ManagedObjectContext an saved this change, how can I inform my fetchedResultsController to perform a new fetch? In my understanding it is not correct to send performFetch-Message agian.
Thanks!
using this delegate methods you can make it posible
fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil];
And set the value of the parameter cacheName to nil. it avoids crash and keeps only current data after ManagedObjectContext change
#pragma mark -
#pragma mark Fetched results controller delegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableViews = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableViews insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableViews deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[_delegate configureCell:[tableViews cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableViews deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableViews insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionMiddle
animated:NO];
}
this code automatically update and reload when you add,delete or update the data in NSFetchedResultsController and UITableViewController
you can use postNotificaton for which you should already have an observer set in your controller which will initiate the fetch request again.